diff --git a/core/modules/update/templates/update-last-check.html.twig b/core/modules/update/templates/update-last-check.html.twig
new file mode 100644
index 0000000..86ed1ff
--- /dev/null
+++ b/core/modules/update/templates/update-last-check.html.twig
@@ -0,0 +1,22 @@
+{#
+/**
+ * @file
+ * Default theme implementation for the last time we checked for update data.
+ *
+ * Available variables:
+ * - last: The timestamp when the site last checked for available updates.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_update_last_check()
+ *
+ * @ingroup themeable
+ */
+#}
+<div class="update checked">
+  {% if last_checked %}
+    {{ 'Last checked: @time ago'|t({'@time': time}) }}
+  {% else %}
+    {{ 'Last checked: never'|t }}
+  {% endif %}
+  <span class="check-manually">({{ link }})</span>
+</div>
diff --git a/core/modules/update/templates/update-report.html.twig b/core/modules/update/templates/update-report.html.twig
new file mode 100644
index 0000000..90e1c80
--- /dev/null
+++ b/core/modules/update/templates/update-report.html.twig
@@ -0,0 +1,14 @@
+{#
+/**
+ * @file
+ * Default theme implementation for the project status report.
+ *
+ * Available variables:
+ *   - data: An array of data about each project's status.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_update_report()
+ *
+ * @ingroup themeable
+ */
+#}
diff --git a/core/modules/update/templates/update-status-label.html.twig b/core/modules/update/templates/update-status-label.html.twig
new file mode 100644
index 0000000..2f036b1
--- /dev/null
+++ b/core/modules/update/templates/update-status-label.html.twig
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an update status label.
+ *
+ * Available variables:
+ * - text: The status label text.
+ * - attributes: Remaining HTML attributes for the element.
+ * - attributes.class: HTML classes that can be used to style contextually
+ *    through CSS.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_update_status_label()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if text %}
+  <span{{ attributes }}>{{ text|t }}</span>
+{% endif %}
diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc
index 0047a52..a6ce460 100644
--- a/core/modules/update/update.manager.inc
+++ b/core/modules/update/update.manager.inc
@@ -67,7 +67,11 @@ function update_manager_update_form($form, $form_state = array(), $context) {
     return $form;
   }
 
-  $form['#theme'] = 'update_manager_update_form';
+  $last = state()->get('update.last_check') ?: 0;
+  $form['update_lask_check'] = array(
+    '#theme' => 'update_last_check',
+    '#last' => $last,
+  );
 
   $available = update_get_available(TRUE);
   if (empty($available)) {
@@ -268,23 +272,6 @@ function update_manager_update_form($form, $form_state = array(), $context) {
 }
 
 /**
- * Returns HTML for the first page in the process of updating projects.
- *
- * @param $variables
- *   An associative array containing:
- *   - form: A render element representing the form.
- *
- * @ingroup themeable
- */
-function theme_update_manager_update_form($variables) {
-  $form = $variables['form'];
-  $last = state()->get('update.last_check') ?: 0;
-  $output = theme('update_last_check', array('last' => $last));
-  $output .= drupal_render_children($form);
-  return $output;
-}
-
-/**
  * Form validation handler for update_manager_update_form().
  *
  * Ensures that at least one project is selected.
diff --git a/core/modules/update/update.module b/core/modules/update/update.module
index 7dee311..21d317c 100644
--- a/core/modules/update/update.module
+++ b/core/modules/update/update.module
@@ -257,21 +257,24 @@ function update_manager_access() {
  */
 function update_theme() {
   return array(
-    'update_manager_update_form' => array(
-      'render element' => 'form',
-      'file' => 'update.manager.inc',
-    ),
     'update_last_check' => array(
       'variables' => array('last' => NULL),
+      'template'  => 'update-last-check',
     ),
     'update_report' => array(
       'variables' => array('data' => NULL),
+      // 'template'  => 'update-report',
     ),
+    // @todo convert to #type=>table and remove this theme function.
+    // @see http://drupal.org/node/1938934.
     'update_version' => array(
       'variables' => array('version' => NULL, 'tag' => NULL, 'class' => array()),
+      'file' => 'update.report.inc',
     ),
     'update_status_label' => array(
       'variables' => array('status' => NULL),
+      'file' => 'update.report.inc',
+      'template' => 'update-status-label',
     ),
   );
 }
@@ -625,13 +628,11 @@ function _update_project_status_sort($a, $b) {
  * @see theme_update_available_updates_form()
  * @ingroup themeable
  */
-function theme_update_last_check($variables) {
+function template_preprocess_update_last_check(&$variables) {
   $last = $variables['last'];
-  $output = '<div class="update checked">';
-  $output .= $last ? t('Last checked: @time ago', array('@time' => format_interval(REQUEST_TIME - $last))) : t('Last checked: never');
-  $output .= ' <span class="check-manually">(' . l(t('Check manually'), 'admin/reports/updates/check', array('query' => drupal_get_destination())) . ')</span>';
-  $output .= "</div>\n";
-  return $output;
+  $variables['last_checked'] = ($last != NULL);
+  $variables['time'] = format_interval(REQUEST_TIME - $last);
+  $variables['link'] = l(t('Check manually'), 'admin/reports/updates/check', array('query' => drupal_get_destination()));
 }
 
 /**
diff --git a/core/modules/update/update.report.inc b/core/modules/update/update.report.inc
index 607b523..b56e615 100644
--- a/core/modules/update/update.report.inc
+++ b/core/modules/update/update.report.inc
@@ -1,5 +1,7 @@
 <?php
 
+use Drupal\Core\Template\Attribute;
+
 /**
  * @file
  * Code required only when rendering the available updates report.
@@ -11,36 +13,51 @@
  * @see update_menu()
  */
 function update_status() {
+  $build = array();
+  $last = state()->get('update.last_check') ?: 0;
+  $build['last_check'] = array(
+    '#theme' => 'update_last_check',
+    '#last' => $last,
+  );
   if ($available = update_get_available(TRUE)) {
     module_load_include('inc', 'update', 'update.compare');
     $data = update_calculate_project_data($available);
-    return theme('update_report', array('data' => $data));
   }
   else {
-    return theme('update_report', array('data' => _update_no_data()));
+    $data = _update_no_data();
+  }
+
+  if (!is_array($data)) {
+    $build['data'] = array(
+      '#markup' => $data,
+      '#prefix' => '<p>',
+      '#suffix' => '</p>',
+    );
+    return $build;
   }
+
+
+  $build['report'] = array(
+    '#theme' => 'update_report',
+    '#data' => $data,
+  );
+  return $build;
 }
 
 /**
- * Returns HTML for the project status report.
+ * Prepares variables the project status report.
+ *
+ * Default template: container.html.twig.
  *
  * @param array $variables
  *   An associative array containing:
  *   - data: An array of data about each project's status.
  *
- * @ingroup themeable
  */
 function theme_update_report($variables) {
   $data = $variables['data'];
 
-  $last = state()->get('update.last_check') ?: 0;
-  $output = theme('update_last_check', array('last' => $last));
-
-  if (!is_array($data)) {
-    $output .= '<p>' . $data . '</p>';
-    return $output;
-  }
-
+  $output = '';
   $header = array();
   $rows = array();
 
@@ -261,23 +278,29 @@ function theme_update_report($variables) {
  * @see update_calculate_project_data()
  * @ingroup themeable
  */
-function theme_update_status_label($variables) {
+function template_preprocess_update_status_label(&$variables) {
+  $variables['attributes'] = new Attribute(array('class' => array()));
   switch ($variables['status']) {
     case UPDATE_NOT_SECURE:
-      return '<span class="security-error">' . t('Security update required!') . '</span>';
-
+      $variables['attributes']['class'] = 'security-error';
+      $variables['text'] = 'Security update required!';
+      break;
     case UPDATE_REVOKED:
-      return '<span class="revoked">' . t('Revoked!') . '</span>';
-
+      $variables['attributes']['class'] = 'revoked';
+      $variables['text'] = 'Revoked!';
+      break;
     case UPDATE_NOT_SUPPORTED:
-      return '<span class="not-supported">' . t('Not supported!') . '</span>';
-
+      $variables['attributes']['class'] = 'not-supported';
+      $variables['text'] = 'Not supported!';
+      break;
     case UPDATE_NOT_CURRENT:
-      return '<span class="not-current">' . t('Update available') . '</span>';
-
+      $variables['attributes']['class'] = 'not-current';
+      $variables['text'] = 'Update available';
+      break;
     case UPDATE_CURRENT:
-      return '<span class="current">' . t('Up to date') . '</span>';
-
+      $variables['attributes']['class'] = 'current';
+      $variables['text'] = 'Up to date';
+      break;
   }
 }
 
