The answer below is explained based on the definition found in RFC 2616
Proxy and server have definitions which use the word program. Whereas, for a gateway it does not. That is one of the distinctions you should notice.
Try to compare a proxy and a gateway by their handling of a request. For a proxy:
"Requests are serviced internally or by passing them on, with
possible translation, to other servers."
It essentially may alter the request or response that get passed through it.
The gateway definition specifies that it:
"acts as an intermediary for some other server. Unlike a proxy, a
gateway receives requests as if it were the origin server for the
requested resource; the requesting client may not be aware that it is
communicating with a gateway."
So, gateway in this context pretty much receives and delivers whatever goes through it.
A tunnel is like a tube with a point at each end. The intermediate program or server is not aware of this connection. This tunnel can be initiated by an HTTP request. The tunnel will be removed when either endpoint decides to drop the tunnel.