diff --git a/doc/protocol.xml b/doc/protocol.xml
index 36ee3c35d..364384e1f 100644
--- a/doc/protocol.xml
+++ b/doc/protocol.xml
@@ -782,11 +782,14 @@ OK
           <term>
             <cmdsynopsis>
               <command>shuffle</command>
+              <arg><replaceable>SONGRANGE</replaceable></arg>
             </cmdsynopsis>
           </term>
           <listitem>
             <para>
               Shuffles the current playlist.
+              <varname>SONGRANGE</varname> is optional and specifies
+              a range of songs.
             </para>
           </listitem>
         </varlistentry>
diff --git a/src/command.c b/src/command.c
index e6401896d..42ea87f77 100644
--- a/src/command.c
+++ b/src/command.c
@@ -656,7 +656,12 @@ static enum command_return
 handle_shuffle(G_GNUC_UNUSED struct client *client,
 	       G_GNUC_UNUSED int argc, G_GNUC_UNUSED char *argv[])
 {
-	shufflePlaylist(&g_playlist);
+	unsigned start = 0, end = queue_length(&g_playlist.queue);
+	if (argc == 2 && !check_range(client, &start, &end,
+	                              argv[1], need_range))
+		return COMMAND_RETURN_ERROR;
+
+	shufflePlaylist(&g_playlist, start, end);
 	return COMMAND_RETURN_OK;
 }
 
@@ -1566,7 +1571,7 @@ static const struct command commands[] = {
 	{ "seek", PERMISSION_CONTROL, 2, 2, handle_seek },
 	{ "seekid", PERMISSION_CONTROL, 2, 2, handle_seekid },
 	{ "setvol", PERMISSION_CONTROL, 1, 1, handle_setvol },
-	{ "shuffle", PERMISSION_CONTROL, 0, 0, handle_shuffle },
+	{ "shuffle", PERMISSION_CONTROL, 0, 1, handle_shuffle },
 	{ "stats", PERMISSION_READ, 0, 0, handle_stats },
 	{ "status", PERMISSION_READ, 0, 0, handle_status },
 #ifdef ENABLE_SQLITE
diff --git a/src/playlist.h b/src/playlist.h
index 7c3eb337a..dcad92ce0 100644
--- a/src/playlist.h
+++ b/src/playlist.h
@@ -151,7 +151,7 @@ void syncPlayerAndPlaylist(struct playlist *playlist);
 
 void previousSongInPlaylist(struct playlist *playlist);
 
-void shufflePlaylist(struct playlist *playlist);
+void shufflePlaylist(struct playlist *playlist, unsigned start, unsigned end);
 
 void
 deleteASongFromPlaylist(struct playlist *playlist, const struct song *song);
diff --git a/src/playlist_edit.c b/src/playlist_edit.c
index 1a76273b4..2c0c62eb6 100644
--- a/src/playlist_edit.c
+++ b/src/playlist_edit.c
@@ -353,42 +353,40 @@ moveSongInPlaylistById(struct playlist *playlist, unsigned id1, int to)
 	return moveSongInPlaylist(playlist, song, to);
 }
 
-void shufflePlaylist(struct playlist *playlist)
+void shufflePlaylist(struct playlist *playlist, unsigned start, unsigned end)
 {
 	const struct song *queued;
-	unsigned i;
 
-	if (queue_length(&playlist->queue) <= 1)
+	if (end-1 <= start || end > queue_length(&playlist->queue))
 		return;
 
 	queued = playlist_get_queued_song(playlist);
+	if (playlist->playing && playlist->current >= 0) {
+		unsigned current_position;
+		current_position = queue_order_to_position(&playlist->queue,
+	                                                   playlist->current);
 
-	if (playlist->playing) {
-		if (playlist->current >= 0)
+		if (current_position >= start && current_position < end)
+		{
 			/* put current playing song first */
-			queue_swap(&playlist->queue, 0,
-				   queue_order_to_position(&playlist->queue,
-							   playlist->current));
+			queue_swap(&playlist->queue, start, current_position);
 
-		if (playlist->queue.random) {
-			playlist->current =
-				queue_position_to_order(&playlist->queue, 0);
-		} else
-			playlist->current = 0;
+			if (playlist->queue.random) {
+				playlist->current =
+					queue_position_to_order(&playlist->queue, start);
+			} else
+				playlist->current = start;
 
-		/* start shuffle after the current song */
-		i = 1;
+			/* start shuffle after the current song */
+			start++;
+		}
 	} else {
-		/* no playback currently: shuffle everything, and
-		   reset playlist->current */
+		/* no playback currently: reset playlist->current */
 
-		i = 0;
 		playlist->current = -1;
 	}
 
-	/* shuffle the rest of the list */
-	queue_shuffle_range(&playlist->queue, i,
-			    queue_length(&playlist->queue));
+	queue_shuffle_range(&playlist->queue, start, end);
 
 	incrPlaylistVersion(playlist);