Sidney Sam, Andre Schurrle and Gonzalo Castro got the goals for the home side with Nando Rafael and Adam Bodzek on target for the visitors, who made life hard for Leverkusen.
The hosts were reduced to 10 men in the 65th minute, with the score at 2-1, when substitute Simon Rolfes was sent off just two minutes after replacing Sam.
But Castro extended their lead and Bodzek's 86th-minute strike was in vain.
Werder Bremen moved above Mainz in the table with a 2-1 win in an entertaining game at the Weser Stadion.
Aaron Hunt scored both goals for Thomas Schaaf's men, the second coming late in the game to render Adam Szalai's earlier equaliser worthless for Thomas Tuchel's side.
Bremen have now picked up seven points in their last three games while Mainz lost for the first time since September 25.
Sunday's Bundesliga Results
Saturday's Bundesliga Results
Friday's Bundesliga Results