diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index b1ca7c03505a1602d6fa560c1fae5ebaf3b390d8..9a0d7139635bf6af7c4f610188000abad3199038 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -2244,6 +2244,8 @@ function template_preprocess_item_list(&$variables) {
  *   - title: The title of the list.
  *   - list_type: The type of HTML list (e.g. "ul", "ol").
  *   - attributes: The attributes applied to the list element.
+ *   - empty: A message to display when there are no items. Allowed value is a
+ *     string or render array.
  */
 function theme_item_list($variables) {
   $items = $variables['items'];
@@ -2277,6 +2279,9 @@ function theme_item_list($variables) {
     }
     $output .= "</$list_type>";
   }
+  elseif (!empty($variables['empty'])) {
+    $output .= render($variables['empty']);
+  }
 
   // Only output the list container and title, if there are any list items.
   // Check to see whether the block title exists before adding a header.
@@ -3040,7 +3045,7 @@ function drupal_common_theme() {
       'variables' => array('status' => MARK_NEW),
     ),
     'item_list' => array(
-      'variables' => array('items' => array(), 'title' => '', 'list_type' => 'ul', 'attributes' => array()),
+      'variables' => array('items' => array(), 'title' => '', 'list_type' => 'ul', 'attributes' => array(), 'empty' => NULL),
     ),
     'feed_icon' => array(
       'variables' => array('url' => NULL, 'title' => NULL),
diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
index 635883ca8434819a5e3951a70ff765e3c50c6d54..69d5ac6e645a0dfcb239c08addcfb53c1b06f229 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
@@ -25,16 +25,30 @@ public static function getInfo() {
    * Tests theme_item_list().
    */
   function testItemList() {
-    // Verify that empty variables produce no output.
+    // Verify that empty items produce no output.
     $variables = array();
     $expected = '';
     $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates no output.');
 
+    // Verify that empty items with title produce no output.
     $variables = array();
     $variables['title'] = 'Some title';
     $expected = '';
     $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback with title generates no output.');
 
+    // Verify that empty items produce the empty string.
+    $variables = array();
+    $variables['empty'] = 'No items found.';
+    $expected = '<div class="item-list">No items found.</div>';
+    $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates empty string.');
+
+    // Verify that empty items produce the empty string with title.
+    $variables = array();
+    $variables['title'] = 'Some title';
+    $variables['empty'] = 'No items found.';
+    $expected = '<div class="item-list"><h3>Some title</h3>No items found.</div>';
+    $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates empty string with title.');
+
     // Verify nested item lists.
     $variables = array();
     $variables['title'] = 'Some title';