The Dane completed the victory with a backhand down the line on a second match point for her 60th match victory of the season.
The 27-year-old Wozniacki’s best previous result at the WTA Finals was reaching the final in 2010.
Williams, who was hoping to win a 50th career title on Sunday, is the only player at this year’s WTA Finals who didn’t win a title during the season.
The 37-year-old Williams appeared in three finals at the five most prestigious tournaments of the season: the Australian Open, Wimbledon, and here in Singapore.
Williams, who won the WTA Finals title in 2008, had won all seven previous matches against Wozniacki.
“Eight is my lucky number so I was hoping if I was going to beat her at least once in my career it would be today,” Wozniacki said. “I just went out there and did my best.”
Wozniacki raced to a 5-0 lead in the second set before Williams mounted a late comeback attempt.
“I didn’t seem to come up with my best tennis until it was too late,” Williams said. “I’ll try to play a little better earlier next time. That might be a good plan.”
Woznicki dropped serve when she was serving for the first set at 5-3, and then dropped serve when serving for the match in the seventh and ninth games of the second set.
“I’m still shaking,” Wozniacki said. “I was up 5-0 and then Venus started upping her game. She went for her shots, started serving into my body. I’m just so happy I managed to win in the end.”