The 10th-seeded Goffin had lost all previous five matches to Djokovic and looked to be heading for another loss when the 12-time Grand Slam winner led 4-2 in the decider.
But Goffin broke him in the eighth game and held firm on his own serve when taken to deuce in a tight 11th game.
The pressure was back on the second-ranked Djokovic to hold and force a tiebreak, but Goffin kept coming at him.
Djokovic saved the first match point with an ace, the second one on his second serve, the third with a stinging forehand winner and a fourth when Goffin chopped a backhand into the net.
A sloppy unforced error on forehand gave Goffin another chance, and he took it with a deep forehand right on the line that Djokovic swiped back off balance into the net.
Goffin, who had taken just one set off Djokovic before Friday, grabbed his head with both hands.
Djokovic, the champion here in 2013 and 2015, hugged him at the net after the match, which took 2 hours, 38 minutes.
After Goffin took the first set in little more than 30 minutes, Djokovic found his range in the second. Goffin saved two sets points on his serve at 5-3 down, but Djokovic held easily on his next service game to level the match.
Cilic, the 2014 U.S. Open champion, seemed to be in command when he broke at the start of the third set. But the Spaniard rallied to set up a semi against Lucas Pouille of France, who beat Pablo Cuevas of Uruguay 6-0, 3-6, 7-5.
Pouille reached the quarterfinals at the U.S. Open and Wimbledon last year in his breakthrough season.
Ramos-Vinolas needed 2 1/2 hours to win, but could have got there faster after leading 5-3 in the tiebreaker -- only for Cilic to level the set score with a volley that only just landed in. He puffed his cheeks in relief.
Cilic won their only previous match on clay five years ago in Hamburg, Germany, but the Spaniard looked sharp here early on. He broke Cilic in the third game and clinched the first set when Cilic's cross-court backhand went out.
Ramos-Vinolas won on his first match point when Cilic double-faulted.
Cuevas was poor in the first set against Pouille, winning no points on his second serve and failing to save any break points. He started to find range with his one-handed backhand in the second set and leveled the set score when Pouille netted a return.
Pouille offered an explanation as to why he lost his way after a one-sided first set.
"I should have gone off the court as well when he went off for a toilet break," Pouille said. "I lost my momentum a bit."
The decider was anyone's guess.
Pouille thumped two heavy forehands to hold serve easily at the start and then broke Cuevas for 2-0.
But Cuevas reeled him back in and served for the match at 5-4.
Pouille stepped up his game and a cross-court backhand gave him break point, which he took when Cuevas sank a backhand into the net.
With Cuevas on serve again at 5-6, Pouille clinched victory on his second match point when the former hit another backhand long.