Yevhen Konoplyanka fired in five minutes after the break and Brazilian defender Naldo struck with a bullet of a shot in the 82nd minute following an indirect free-kick for a first Schalke win against Ruhr rivals Dortmund in seven games.
Leipzig meanwhile moved fifth with a 1-1 draw at midtable Werder Bremen.
Dortmund and Schalke teams had drawn 4-4 earlier in the season when visiting Schalke came from 4-0 down, but this was a much tighter encounter in Gelsenkirchen with few clearcut chances until the game opened up towards the end.
Former Schalke striker Raul was in the stadium to see his old side have the better of a hard-fought affair, and will have admired both goals, particularly Naldo's belter from nearly 30 metres after the Brazilian was teed up for the shot by Daniel Caliguiri.
Caliguiri had also set up the first goal after robbing Marcel Schmelzer of the ball on the half-way line and passing into the path of Konoplyanka who finished emphatically with a left-shot inside the near post.
Schalke coach Domenico Tedesco said he was relieved to get the three points after a six-game winning series came to an end last weekend with a 3-2 defeat at Hamburg.
"It was a super first-half. We managed to remain compact and often got forward on the flanks," he said.
"We scored the goals in the second half and defended well to the end. I am delighted for the team and the fans."
Dortmund midfield Marco Reus told Sky Sport: "We didn't play well in the first half, Schalke used the space well and had more chances that we did.
"They scored the first goal and it was clear we had to go forward...we had more chances then but after the second goal it was obviously difficult."
Schalke move to 55 points, four ahead of Bayer Leverkusen and Dortmund - and now eight ahead of fifth-placed Leipzig with four matches remaining in the race for a top-four spot and Champions League qualification.
Tedesco's side are also fighting for a place in the German Cup final, with a semi-final match against Eintracht Frankfurt on Wednesday.
Bayern Munich, who thrashed Borussia Moenchengladbach on Saturday, have a 20-point lead after securing a sixth straight league title last weekend.
In Bremen, the home side took the lead against Leipzig when Niklas Moisander finished in the 28th minute after a shot from Max Kruse came back off the bar.
Bremen could have increased the lead before the break but Ademola Lookman levelled for Leipzig in the 50th minute and both sides had chances to win the game in an end-to-end closing stage.
Leipzig have 47 points, four behind Dortmund and Leverkusen, and now a point ahead of Hoffenheim and Frankfurt. Bremen remain in midtable, 10 points clear of Mainz in the relegation play-off place and all but safe from relegation danger.
Mainz meet fellow strugglers Freiburg on Monday evening.