Almog Cohen and Dario Lezcano gave them a comfortable 2-0 advantage at the break before Pierre-Emerick Aubameyang hit back for BVB.
Lezcano scored his second in the same minute, though Adrian Ramos and Christian Pulisic rescued a point.
Markus Kauczinski made just two changes from Ingolstadt's last game, as Florent Hadergjonaj and Lezcano came in for Tobias Levels and Stefan Lex. Thomas Tuchel was more active in his team selection and opted for five alterations. Roman Weidenfeller, Gonzalo Castro, Joo-Ho Park, Lukasz Piszczek and Ramos started in place of Roman Bürki, Mario Götze, Felix Passlack, Pulisic and Sokratis.
Ingolstadt take advantage of lacklustre BVB
It was a slow start to the game in which neither side got anywhere near the goal within the opening five minutes, although that all changed when Ingolstadt earned a free-kick. Markus Suttner's delivery was superb and Cohen timed his run to absolute perfection, allowing him to fire past the helpless Weidenfeller from close range.
They almost had a second not long later, as another set piece troubled the Borussia back-line and Marvin Matip's knock-down was acrobatically volleyed at goal by Lukas Hinterseer, but it was well held by Weidenfeller. At the other end, Ousmane Dembélé and Julian Weigl stung the palms of Ørjan Nyland.
Tuchel's side still did not pay heed to the threat posed by Ingolstadt at dead ball situations and paid the price once more. Suttner's delivery proved profitable once again as it was Lezcano who glanced a header past the static BVB defence and into the far corner; the visiting fans behind the goal could hardly believe their eyes.
Weigl tried his had from distance in a bid to bring his side back into the game, though Nyland saved his attempt with relative ease. From there, Hinterseer wasted another excellent chance by volleying into the groynd and over while Lezcano saw his near-post prod poked behind by Weidenfeller; the visitors were grateful to get to the break.
BVB battle back and grab a late equaliser
Dortmund started the second period by bringing on Pulisic in a bid to brighten up their attack. However, with Ingolstadt guarding a two-goal lead the Schanzer were more than happy to bide their time in coming out of defensive shape. Castro and Marc Bartra had early chances, yet couldn't find the target when it mattered most.
Just before the hour mark, things finally clicked for Tuchel and the visitors. The ball was shifted wide into Dembélé's feet and the tricky winger managed to wriggle free and find space to whip into a great ball to the back post where Aubameyang rose highest to direct the ball from back where it came and give some hope to their cause.
But that was quickly wiped out within 60 seconds, as the old adage of being vulnerable after conceding rang true. Some good work down the right saw Florent Hadergjonaj drill a low ball into the feet of Lezcano, who caught Weidenfeller off guard with a first-time finish that just crept underneath the veteran's gloves.
Ingolstadt went forward immediately after scoring and should have settled the game when Moritz Hartmann was sent through on goal, only to see his half-volley rattle the base of the post. That didn't deter BVB and they grabbed another one back, this time Ramos took advantage of some superb build-up from Pulisic to tap into an empty net.
Pulisic was the man to grab a late, great equaliser and sent the visiting fans delirious in the 91st minute. After Nyland had made a great reaction save, the ball fell kindly for the American to touch the ball over the line from a yard out; Ingolstadt were understandably heartbroken.
Dortmund pushed for the winner but found Nyland in inspired form to deny Passlack's thunderous effort from range and Götze's shot from eight yards. It was dramatic from start to finish but far from the result that either side would have wanted.