Schalke continued to cause problems, and doubled their advantage midway through the first half when Maxim Choupo-Moting found the bottom corner following a poor clearance from Adrian Ramos, who failed to clear the danger after Roman Weidenfeller had kept out Klaas-Jan Huntelaar's header.
Ramos would make up for his error just three minutes later as he led a Dortmund attack before finding the run of Pierre-Emerick Aubameyang, who reduced the deficit with a calm finish.
The match continued to be an end-to-end affair either side of the break, with Schalke missing a great chance to extend the lead early in the second half when Kevin-Prince Boateng curled wide from the edge of the box.
Despite enjoying slightly more possession than their rivals for long spells, Dortmund struggled to create chances in the final third as Schalke's stubborn defence made life difficult as the game entered its closing stages.
As a result of the pressure from the visitors, Schalke were forced to curb their attacking instincts, but they held on to secure a valuable win over their rivals.