Spain upset defending hockey champions Belgium, India beat Britain
The Netherlands also topped Australia 2-0 in a physical contest, India beat Britain 4-2 on penalties following a 1-1 draw and Germany edged Argentina 3-2.
Germany will play India in the semis, while the Netherlands face Spain.
Spain had not made it past the last eight since Beijing 2008, while Belgium reached the last two Olympic finals, with several of their players holding gold and silver medals from the Tokyo and Rio Games respectively.
Forward Jose Maria Basterra opened the scoring in the 40th minute by converting a goalkeeper deflection off a blistering pass from defender Jordi Bonastre but the lead did not last long as Belgium's Arthur de Sloover equalised a minute later.
Forward Marc Reyne put Spain back in front after 55 minutes with a strike from the field and Miralles stretched the lead before Alexander Hendrickx pulled a goal back.
"I think today is the best day of my life," Basterra said.
"We had pointed to this day in our calendar, and now we are so happy. We have to enjoy today and tomorrow we will see (face) our opponents and we will see how to beat them."
India, who captured the last of their eight Olympic hockey gold medals in 1980, beat Britain after playing with 10 men for most of the match following a red card for a reckless high stick by defender Amit Rohidas in the 17th minute.
The final penalty score by substitute Raj Kumar Pal put the once dominant side in the semi-finals for the second Olympics in a row, after they won bronze in Tokyo.
The Netherlands had several players limp off the field as the match against Australia got physical, with some shoving between players.
The Dutch came out on top, however, as Thijs van Dam widened the lead by slicing through two defenders with the ball in the 41st minute and angling a shot across his body to beat keeper Pirmin Blake for the Netherlands' second score of the match.