Schalke twice equalised but could only watch as Sven Schipplock scored the winner for Hoffenheim in added time as the visitors missed a chance to keep pace with Bundesliga leaders Bayern Munich.
Kevin Volland gave Hoffenheim the lead in the 13th minute with Roman Neustadter equalising in the 37th minute.
Roberto Firmino's penalty after 67 minutes pushed Hoffenheim ahead once again before Atsuto Uchida equalised again in the 82nd minute. But Schipplock scored a minute into injury time to seal the victory.
Hoffenheim ended a four-match winless streak to improve to 11 points while Schalke suffered their first defeat away from home to remain on 20 points.
The first chance of the game turned into the first goal for the hosts in the 13th minute as Fabian Johnson raced forward on the counter and fed Volland, who outran Joel Matip and beat Schalke keeper Lars Unnerstall to make it 1-0.
It was just the second goal conceded by Schalke in the first half of a league game this season.
Schalke struggled to generate much in attack but equalised in the 37th minute from a set piece as Jefferson Farfan's corner from the right was headed home from Neustadter just inside the far left post.
Schalke pushed forwards looking to take the lead before the break but Ibrahim Afellay's goal in the 42nd minute was disallowed after a foul and Hoffenheim keeper Tim Wiese made two great saves a minute later from shots by Jermaine Jones and Farfan and against Afellay in the 45th minute.
Klaas Jan Huntelaar headed just wide in the 50th minute, Wiese made a great double save two minutes later from Farfan and Afellay, and Jones headed just wide right in the 61st minute.
But it was Hoffenheim who grabbed the lead after 67 minutes through a penalty which was awarded for Matip's foul on Volland in the box. Firmino stepped up and scored to make it 2-1.
Schalke equalised in the 82nd minute as Farfan crossed from the right side to Huntelaar whose back heal attempt was slowed by Wiese but into the path of the charging Uchida, who blasted in from three yards out.
Ciprian Marica's header in the 88th minute went just over the bar for Schalke.
And substitute Schipplock earned Hoffenheim the win in injury time, running onto a through ball from Firmino and scoring.