Florian Wirtz opened the scoring for Leverkusen with a toe poke in the ninth minute, but striker Haaland equalised with a towering header in the 37th before Jude Bellingham had a second for Dortmund ruled out due to a foul in the build-up.
Patrik Schick scored in first-half stoppage time to put Leverkusen 2-1 up and there was to be no let-up after the break.
Julian Brandt levelled again in the 49th minute, deftly controlling Haaland’s pass with his heel before rifling the ball into the roof of the net, but within six minutes Leverkusen were ahead again through Moussa Diaby‘s strike from the edge of the area.
Again Dortmund equalised, this time through a superb Raphael Guerreiro free kick, and they went into a 4-3 lead from the penalty spot in the 77th minute when Haaland fired home after Marco Reus was struck in the face by the arm of Odilon Kossounou.
Elsewhere, VfL Wolfsburg remained top of the table with a comfortable 2-0 win over struggling Greuther Furth, while FC Cologne managed to hang on for a 1-1 draw at Freiburg despite losing Florian Kainz to a second yellow card in the 74th minute.
Mainz scored a goal in each half as they beat Hoffenheim 2-0 while Union Berlin were held to a scoreless draw at home to Augsburg.
Wolfsburg have a maximum 12 points after four games, with Dortmund second on nine points and Mainz behind them on goal difference. Freiburg are fourth on eight points.