diff --git a/src/output/httpd_client.c b/src/output/httpd_client.c
index 266a207..2f4b1d6 100644
--- a/src/output/httpd_client.c
+++ b/src/output/httpd_client.c
@@ -85,6 +85,39 @@ struct httpd_client {
 	 * #current_page.
 	 */
 	size_t current_position;
+
+	/* ICY */
+  
+	/**
+	 * If we should sent icy metadata.
+	 */
+	gboolean icy_metadata_requested;
+
+	/**
+	 * If the current metadata was already sent to the client.
+	 */
+	gboolean icy_metadata_sent;
+
+	/**
+	 * The amount of streaming data between each metadata block
+	 */
+	guint icy_metaint;
+
+	/**
+	 * The metadata as #page which is currently being sent to the client.
+	 */
+	struct page *icy_metadata;
+
+	/*
+	 * The amount of bytes which were already sent from the metadata.
+	 */
+	size_t icy_current_position;
+
+	/**
+	 * The amount of streaming data sent to the client
+	 * since the last icy information was sent.
+	 */
+	guint icy_fill;
 };
 
 static void
@@ -170,6 +203,12 @@ httpd_client_handle_line(struct httpd_client *client, const char *line)
 			httpd_client_begin_response(client);
 			return true;
 		}
+		
+		if (strncmp(line, "Icy-MetaData: 1", 15) == 0) {
+			/* Send icy metadata */
+			client->icy_metadata_requested = TRUE;
+			return true;
+		}
 
 		/* expect more request headers */
 		return true;
@@ -217,19 +256,40 @@ httpd_client_send_response(struct httpd_client *client)
 	gsize bytes_written;
 
 	assert(client->state == RESPONSE);
-
-	g_snprintf(buffer, sizeof(buffer),
-		   "HTTP/1.1 200 OK\r\n"
-		   "Content-Type: %s\r\n"
-		   "Connection: close\r\n"
-		   "Pragma: no-cache\r\n"
-		   "Cache-Control: no-cache, no-store\r\n"
-		   "\r\n",
-		   client->httpd->content_type);
+	
+	if (!client->icy_metadata_requested) {
+		g_snprintf(buffer, sizeof(buffer),
+							 "HTTP/1.1 200 OK\r\n"
+							 "Content-Type: %s\r\n"
+							 "Connection: close\r\n"
+							 "Pragma: no-cache\r\n"
+							 "Cache-Control: no-cache, no-store\r\n"
+							 "\r\n",
+							 client->httpd->content_type);
+	} else {
+		g_snprintf(buffer, sizeof(buffer),
+							 "ICY 200 OK\r\n"
+							 "icy-notice1:<BR>This stream requires an audio player!<BR>\r\n" /* TODO */
+							 "icy-notice2:MPD - The music player daemon<BR>\r\n"
+							 "icy-name: Add config information here!\r\n"             /* TODO */
+							 "icy-genre: Add config information here!\r\n"            /* TODO */
+							 "icy-url: Add config information here!\r\n"              /* TODO */
+							 "icy-pub:1\r\n"
+							 "icy-metaint:%d\r\n"
+							 /* TODO "icy-br:%d\r\n" */
+							 "Content-Type: %s\r\n"
+							 "Connection: close\r\n"
+							 "Pragma: no-cache\r\n"
+							 "Cache-Control: no-cache, no-store\r\n"
+							 "\r\n",
+							 client->icy_metaint,
+							 client->httpd->content_type);
+	}
 
 	status = g_io_channel_write_chars(client->channel,
-					  buffer, strlen(buffer),
-					  &bytes_written, &error);
+																		buffer, strlen(buffer),
+																		&bytes_written, &error);
+
 	switch (status) {
 	case G_IO_STATUS_NORMAL:
 	case G_IO_STATUS_AGAIN:
@@ -384,6 +444,13 @@ httpd_client_new(struct httpd_output *httpd, int fd)
 
 	client->input = fifo_buffer_new(4096);
 	client->state = REQUEST;
+	
+	client->icy_metadata_requested = FALSE;
+	client->icy_metadata_sent = TRUE;
+	client->icy_metaint = 8192; /*TODO: just a std value */
+	client->icy_metadata = NULL;
+	client->icy_current_position = 0;
+	client->icy_fill = 0;
 
 	return client;
 }
@@ -439,9 +506,45 @@ write_page_to_channel(GIOChannel *channel,
 	assert(position < page->size);
 
 	return g_io_channel_write_chars(channel,
-					(const gchar*)page->data + position,
-					page->size - position,
-					bytes_written_r, error);
+					    (const gchar*)page->data + position,
+					    page->size - position,
+					    bytes_written_r, error);
+}
+
+static GIOStatus
+write_n_bytes_to_channel(GIOChannel *channel, const struct page *page, 
+					size_t position, gint n,
+					gsize *bytes_written_r, GError **error)
+{
+	GIOStatus status;
+
+	assert(channel != NULL);
+	assert(page != NULL);
+	assert(position < page->size);
+
+	if (n == -1) {
+		status =  write_page_to_channel (channel, page, position,
+																		 bytes_written_r, error);
+	} else {
+		status = g_io_channel_write_chars(channel,
+																			(const gchar*)page->data + position,
+																			n, bytes_written_r, error);
+	}
+	
+	return status;
+}
+
+static gint
+bytes_left_till_metadata (struct httpd_client *client)
+{
+	assert(client != NULL);
+  
+	if (client->icy_metadata_requested &&
+			client->current_page->size - client->current_position
+			> client->icy_metaint - client->icy_fill)
+		return client->icy_metaint - client->icy_fill;
+
+	return -1;
 }
 
 static gboolean
@@ -453,6 +556,7 @@ httpd_client_out_event(GIOChannel *source,
 	GError *error = NULL;
 	GIOStatus status;
 	gsize bytes_written;
+	gint bytes_to_write;
 
 	g_mutex_lock(httpd->mutex);
 
@@ -470,14 +574,62 @@ httpd_client_out_event(GIOChannel *source,
 		client->current_page = g_queue_pop_head(client->pages);
 		client->current_position = 0;
 	}
+	
+	bytes_to_write = bytes_left_till_metadata(client);
+	
+	if (bytes_to_write == 0) {
+		gint metadata_to_write;
+		
+		metadata_to_write = client->icy_current_position;
+		
+		if (!client->icy_metadata_sent) {
+			status = write_page_to_channel(source,
+																		 client->icy_metadata,
+																		 metadata_to_write,
+																		 &bytes_written, &error);
+			
+			client->icy_current_position += bytes_written;
+
+			if (client->icy_metadata->size 
+					- client->icy_current_position == 0) {
+				client->icy_fill = 0;
+				client->icy_current_position = 0;
+				client->icy_metadata_sent = TRUE;
+			}
+		} else {
+			struct page *empty_meta;
+			guchar empty_data = 0;
+			
+			empty_meta = page_new_copy(&empty_data, 1);
+			
+			status = write_page_to_channel(source,
+																		 empty_meta,
+																		 metadata_to_write,
+																		 &bytes_written, &error);
+
+			client->icy_current_position += bytes_written;
+
+			if (empty_meta->size 
+					- client->icy_current_position == 0) {
+				client->icy_fill = 0;
+				client->icy_current_position = 0;
+			}
+		}
+		
+		bytes_written = 0;
+	} else {
+		status = write_n_bytes_to_channel(source, client->current_page,
+																			client->current_position, bytes_to_write,
+																			&bytes_written, &error);
+	}
 
-	status = write_page_to_channel(source, client->current_page,
-				       client->current_position,
-				       &bytes_written, &error);
 	switch (status) {
 	case G_IO_STATUS_NORMAL:
 		client->current_position += bytes_written;
 		assert(client->current_position <= client->current_page->size);
+		
+		if (client->icy_metadata_requested)
+			client->icy_fill += bytes_written;
 
 		if (client->current_position >= client->current_page->size) {
 			page_unref(client->current_page);
@@ -539,3 +691,20 @@ httpd_client_send(struct httpd_client *client, struct page *page)
 			g_io_add_watch(client->channel, G_IO_OUT,
 				       httpd_client_out_event, client);
 }
+
+void
+httpd_client_send_metadata(struct httpd_client *client, struct page *page)
+{
+	if (client->state != RESPONSE)
+		/* the client is still writing the HTTP request */
+		return;
+	
+	if (client->icy_metadata)
+		page_unref(client->icy_metadata);
+	
+	g_return_if_fail (page);
+
+	page_ref(page);
+	client->icy_metadata = page;
+	client->icy_metadata_sent = FALSE;
+}
diff --git a/src/output/httpd_client.h b/src/output/httpd_client.h
index c81cdb1..80ab6bc 100644
--- a/src/output/httpd_client.h
+++ b/src/output/httpd_client.h
@@ -62,4 +62,10 @@ httpd_client_cancel(struct httpd_client *client);
 void
 httpd_client_send(struct httpd_client *client, struct page *page);
 
+/**
+ * Sends the passed metadata.
+ */
+void
+httpd_client_send_metadata(struct httpd_client *client, struct page *page);
+
 #endif
diff --git a/src/output/httpd_output_plugin.c b/src/output/httpd_output_plugin.c
index 96491c4..c0c3afb 100644
--- a/src/output/httpd_output_plugin.c
+++ b/src/output/httpd_output_plugin.c
@@ -354,11 +354,43 @@ httpd_output_play(void *data, const void *chunk, size_t size, GError **error)
 }
 
 static void
+httpd_send_metadata(gpointer data, gpointer user_data)
+{
+	struct httpd_client *client = data;
+	struct page *icy_metadata = user_data;
+
+	httpd_client_send_metadata(client, icy_metadata);
+}
+
+static void
 httpd_output_tag(void *data, const struct tag *tag)
 {
 	struct httpd_output *httpd = data;
+	struct page *icy_metadata;
+	guchar icy_length = 1;
+	gchar meta[1 + 255 * 16]; // Length + Infos = 4081
+	size_t meta_length = 0;
+
+	// The leading n is a placeholder for the length information
+	meta_length = g_snprintf(meta, sizeof(meta),
+													 "nStreamTitle='%s - %s - %s';"
+													 "StreamUrl='';",
+													 tag_get_value(tag, TAG_ITEM_ALBUM),
+													 tag_get_value(tag, TAG_ITEM_ARTIST),
+													 tag_get_value(tag, TAG_ITEM_TITLE));
+
+	meta_length--; // substract placeholder
+
+	icy_length += (icy_length % 16 == 0) ? (int)meta_length
+																			 : ((int)(meta_length / 16) + 1) * 16;
+
+	meta[0] = (icy_length - 1) / 16;
+
+	icy_metadata = page_new_copy(meta, icy_length);
+
+	g_list_foreach(httpd->clients, httpd_send_metadata, icy_metadata);
 
-	/* XXX add suport for icy-metadata */
+	page_unref(icy_metadata);
 
 	encoder_tag(httpd->encoder, tag, NULL);
 }
