Runaway leaders Bayern twice trailed before Jerome Boateng's first goal for the club four minutes from time earned them a narrow win.
Mathis Bolly put the visitors in front in the 16th minute, but Thomas Muller replied on the stroke of half-time. Andreas Lambertz gave the visitors the lead for the second time in the 71st minute, but Franck Ribery equalised three minutes later to set up the late victory.
The win extended Bayern's lead at the top to 20 minutes as Borussia Dortmund lost 2-1 at derby rivals Schalke.
Julian Draxler got the home team on their way to victory on 11 minutes with Klaas Jan Huntelaar doubling their advantage on 35. The defending champions tried to respond in the second half, but only had a Robert Lewandowski consolation goal to show for their efforts.
The win sent Schalke up to fourth, seven points behind their opponents and six below Bayer Leverkusen, who missed the chance to go second by losing 1-0 at Mainz. Andreas Ivanschitz netted the game's only goal from the penalty spot in the 61st minute to lift the hosts to sixth.
Wolfsburg eased their relegation worries with a thumping 5-2 win at Freiburg.
Max Kruse put Freiburg ahead in the second minute, but an own goal from Cedric Makiadi and fine strikes from Vieirinha and Ivica Olic turned the game on its head within 20 minutes.
Olic's second gave Dieter Hecking's side an even more comfortable lead after the break before Johannes Flum scored a second for the home team. Diego added a fifth Wolfsburg goal with the last kick of the game as they opened a nine-point cushion over the relegation zone.
Hoffenheim picked up a crucial victory in the fight against the drop with a 3-0 success at bottom club Greuther Furth. Roberto Firmino gave Hoffenheim the lead in the 10th minute, Joselu made it 2-0 after 16 minutes and Weis wrapped up the win five minutes into the second half.
The win moved second-bottom Hoffenheim two points off Augsburg in the relegation play-off spot, and five ahead of Furth.
In the late kick-off Borussia Monchengladbach and Werder Bremen drew 1-1.
Peniel Mlapa gave Monchengladbach the lead in the 72nd minute, but Aleksandar Ignjovski equalised for the visitors five minutes later.