If you are asking in a general sense, then the answer is most definitely "yes", any HTTP method (like POST) requires a TCP connection, and the only way to initiate a TCP connection is to use the three way handshake.
IF, however, you are asking in a specific case, maybe if you are capturing your own traffic and don't see the 3 way handshake after you submit content to a website, then the answer is a little less simple. We'll have to discuss a few HTTP related concepts before we can properly answer it...
In the original release of HTTP1.0, every object you requested from a webpage required a new TCP connection to be formed for each object. Take the following simplistic website that includes some text, and two images:
<HTML>
<HEAD>
<TITLE>My Title</TITLE>
</HEAD>
<BODY>
Stack Exchange Rules!
<IMG SRC="a.gif">
<IMG SRC="b.gif">
</BODY>
</HTML>
In traditional HTTP1.0, to load this website into your browser would require three TCP connections (each with their own 3-way handshake, and 4-way closure).
HTTP 1.0:
--> SYN
SYN ACK <--
--> ACK
--> GET /index.html
<index.html> <--
--> FIN
ACK <--
FIN <--
--> ACK
.
--> SYN
SYN ACK <--
--> ACK
--> GET /a.gif
<a.gif> <--
--> FIN
ACK <--
FIN <--
--> ACK
.
--> SYN
SYN ACK <--
--> ACK
--> GET /b.gif
<b.gif> <--
--> FIN
ACK <--
FIN <--
--> ACK
Note there are 27 packets above, just to download three items: The HTML page itself (index.html), image a.gif, and image b.gif. (there would actually be more than 27 packets, but to save vertical space, I only included the ACK's in the 3-way-handshake and the 4-way-closure, and omitted ACK's within the data stream)
To improve the efficiency of HTTP, a feature called "Connection Keepalive" was introduced, which allows HTTP to re-use the same TCP connection to request for multiple objects. The transfer above would be reduced to the following:
HTTP 1.1 with Connection Keepalive
--> SYN
SYN ACK <--
--> ACK
--> GET /index.html
<index.html> <--
--> GET /a.gif
<a.gif> <--
--> GET /b.gif
<b.gif> <--
--> FIN
ACK <--
FIN <--
--> ACK
Notice that only a single TCP connection was used to request all three objects. This time, it only took 13 packets, a large improvement from the 27 from earlier.
The last imrpovement to HTTP that we must discuss is a feature called Pipelining. This feature further increased HTTP's efficiency, by making it so the Client can requests multiple options at once, without waiting to receive the prior asked object. Let me show you:
HTTP1.1 with Pipelining
--> SYN
SYN ACK <--
--> ACK
--> GET /index.html
--> GET /a.gif
--> GET /b.gif
<index.html> <--
<a.gif> <--
<b.gif> <--
--> FIN
ACK <--
FIN <--
--> ACK
We're still only using one TCP connection, and we're still only using 9 packets. However, we don't have to wait the Round Trip Time (RTT) it takes between the Client and the Server in between asking for and receiving each object. If you need an analogy, imagine you're at a Restaurant, and you need Salt, Pepper, and Ketchup. Is it more efficient to ask your waiter/waitress for all three items at once, or to ask for them one at a time and wait for them to come back before making the next request?
(Pipelining isn't directly related to your question, but is often described in conjunction with Keepalives and other HTTP efficiency features, so I decided to include it in this answer for completeness)
Now we can finally come back to your question:
Is a TCP three-way handshake required for an HTTP POST?
If you open a connection to a web server and download a webpage using the GET method, and that webserver supports connection keepalive. Subsequent requests to that web server, including the POST method, might simply re-use the already existing TCP connection. Therefore, that particular POST would not require a new 3-way handshake, since the data would be transferred in an already existing TCP connection.
Connection Keepalive, however, does not have an infinite duration. So if after downloading the webpage, you waited a while before sending your POST, the original TCP connection may have already closed, and in this case, your browser would have to open a new TCP connection to POST your data, which would obviously require starting with the 3-way handshake.
Since many browsers and webservers use different timers for how long they want their "connection keepalive" feature to keep connections alive, I wouldn't be able to give you reliable numbers as to how long it typically asks.