The hosts will meet Australia in the semi-final tomorrow.
It was a far from impressive performance by the Indians, who are touted as title contenders as they fumbled in almost all departments of the game.
A packed Major Dhyan Chand Stadium stadium heaved a sigh of relief when Simranjeet Singh (57th) equalised for India after Marc Serrahima gave Spain the lead in the 22nd minute.
The Indians earned as many as nine penalty corners but could utilise just two with Harmanpreet converting the hosts' eighth set piece in the 66th minute to clinch a last four berth.
More From This Section
Even though they enjoyed their share of ball possession, Indians looked completely off-colour in the opening half.
There was a distinct lack of co-ordination. There were sloppy mistakes while trapping and releasing the ball during the first half.
The Indian colts though created more openings but Spain utilised the lone opportunity thet got in the first half.
Spain came out with a tight defensive structure and relied on man marking to stop the attacking Indians.
Spain then took the lead in the 22nd minute through Serrahima's penalty corner conversion much to the stunned silence of the partisan crowd.
Three minutes later Mandeep Singh's deflection from Santa Singh's cross found the back of the Spanish net but it was disallowed by the umpire because of raising ball to go into the breather trailing by a goal.
Four minutes into second half, Spain almost extended their lead but custodian Vikas Dahiya came to his side's rescue to deny Serrahima.
The Indians continued to attack but goals eluded them as Spanish goalkeeper Perez came up with a double save to deny Armaa Qureshi first and then Manpreet (Jr) from the rebound.
It was story of missed chances as India wasted two more penalty corners soon.
Nilkanta Sharma then came close in the 53rd minute but his deflection from Harmanpreet's defence splitting pass went just wide of the goal.
In the last 10 minutes, India got four more penalty corners and the penultimate one was eventually converted by Harmanpreet to take the lead for the first time in the match.
It was a tense last couple of minutes for the hosts as they were reduced to 10 men after Armaan was shown yellow card for an unnecessary tackle.
Earlier in the day, Belgium defeated Argentina in a shoot-out to set up a semi-final clash against six-time champions and title holders Germany.
Belgium eked out a 4-1 win over Argentina in the shoot-out after both the teams were locked 1-1 at the end of regulation time in the first quarterfinal of the day.
In the shoot-out, Nicolas Poncelet, Arthur de Sloover, Victor Wegnez and Henri Raes converted their chances while Tomas Domene was the lone lucky player for Argentina.
Germany had a relatively easy outing against England as they recorded a comfortable 4-2 win to seal their place in the last-four round.
The Germans raced to a two goal lead in the first half through Jan Schiffer (22nd) and Lukas Windfeder (31st) before Florian Scholten (52nd) and Tim Herzbruch (70th) found the net after change of ends for the defending champions.
Later in the day, Kiran Arunasalam drew the first blood for Australia with a fine field goal in the 18th minute before Jip Janssen (47th) equalised for Netherlands from a penalty corner.
Jack Welch then scored the winner for Australia in the 58th minute to take his side to the semi-finals.