It's carnival season in the Rhineland, and Leverkusen fans, many of them in costume, had plenty to celebrate as Xabi Alonso's team proved their title credentials on Saturday (Sunday AEDT).
It was Leverkusen's 31st game this season without a loss in all competitions.
After a kick-off delayed by fan protests, it was a Bayern player who scored the first goal - but he wasn't playing for Bayern.
Right back Josip Stanisic, sent out on loan to Leverkusen at the start of the season, popped up at the far post to score off Robert Andrich's low cross in the 18th minute after Bayern seemed to be taken by surprise by Leverkusen's quick throw-in routine.
Stanisic put his hands up in apology and barely celebrated his first Bundesliga goal in nearly two years, though his teammates certainly did.
Leverkusen made it 2-0 with an incisive counter early in the second half, Grimaldo sprinting down the left flank and playing a one-two with Nathan Tella before lofting a shot over goalkeeper Manuel Neuer.
Jeremie Frimpong added a third in stoppage time into the empty net after Neuer had gone up for a Bayern corner.
Harry Kane has scored 24 goals in 20 Bundesliga games since joining Bayern, but he had few chances to score as Leverkusen squeezed him out of the game.
The referee took the players to the locker rooms in the first half after stoppages to clear away tennis balls thrown by Union fans.
When play resumed, there was another interruption when Wolfsburg fans threw more balls.
Long-running protests against the German league's plans to sell a stake of revenue to an outside investor have intensified as talks are held with prospective buyers.
Danilho Doekhi headed the only goal for Union in the 21st minute of first-half stoppage time.
Fifth-place Leipzig drew 2-2 at Augsburg to lose more ground in the race for the Champions League places. Leipzig have four points from five games since the new year.
American midfielder Lennard Maloney scored his first career Bundesliga goal for Heidenheim in a 2-1 win at Werder Bremen, Eintracht Frankfurt were held to a 1-1 draw by Bochum, and Borussia Moenchengladbach and Darmstadt played out a 0-0 draw.