Schalke had won only one of its last 12 games to drop to 15th place in the Bundesliga, but it
came from behind to stun Dortmund, which had two players sent off within five minutes of each other in the second half.
The game turned on a handball call in the 16th minute, two minutes after Dortmund opened the scoring. Schalke's Daniel Caligiuri converted a penalty kick after a handball decision against Julian Weigl.
Dortmund star Marco Reus and then Marius Wolf were sent off for challenges on Schalke's Suat Serdar. After the Reus' red card, Caligiuri curled the free kick into the top corner to give Schalke a 3-1 lead.
While Dortmund had two straight red cards, McKennie was one of six Schalke players issued yellow cards. He exited the game in the 77th minute. A minute later, Christian Pulisic came on as a substitute for Dortmund.
Bayern can now take a four-point lead at the top with three games to play with a win at struggling Nuremberg on Sunday.