Despite a quick start by Dortmund, which saw a long-range Thomas Meunier effort tipped onto the post within a minute, Frankfurt struck first after a quarter of an hour from a set-piece.
Filip Kostic’s delivery was tapped home by Rafael Santos Borre, despite Gregor Kobel’s best efforts to keep it out.
Borre got his brace less than ten minutes later, finishing well into the bottom-left corner.
Dortmund almost hit back at the end of the first half. Marco Reus’s corner was met by Mats Hummels, but Kevin Trapp made a fine stop before Donyell Malen smacked the rebound against the post.
The visitors eventually got their teeth into it with twenty minutes to go, as substitute Thorgan Hazard finished well from inside the box.
Jude Bellingham equalised for the visitors with three minutes to go, heading in Thomas Meunier’s cross to get Dortmund back level.
A famous victory was sealed by Mahmoud Dahoud in the 89th minute, as the midfielder’s long-range effort found the bottom corner.