Each thread gets its own storage slot. This makes it useful to store a thread specific value. The classic example is SetLastError(), GetLastError().
Now, consider how you would implement that functionality without some sort of thread local storage. Another example is being able to return a pointer to something in a thread safe manner. See gethostbyname(), etc.
// On process intialization.
// Get an index to an available slot.
g_idxLastError = TlsAlloc();
void SetLastError(DWORD dwErr)
TlsSetValue(g_idxLastError, (LPVOID) dwErr);
return (DWORD) TlsGetValue(g_idxLastError);