diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index b38892d..e701101 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -93,7 +93,7 @@ function comment_help($path, $arg) {
       $output .= '<dt>' . t('Default and custom settings') . '</dt>';
       $output .= '<dd>' . t("Each <a href='@content-type'>content type</a> can have its own default comment settings configured as: <em>Open</em> to allow new comments, <em>Hidden</em> to hide existing comments and prevent new comments, or <em>Closed</em> to view existing comments, but prevent new comments. These defaults will apply to all new content created (changes to the settings on existing content must be done manually). Other comment settings can also be customized per content type, and can be overridden for any given item of content. When a comment has no replies, it remains editable by its author, as long as the author has a user account and is logged in.", array('@content-type' => url('admin/structure/types'))) . '</dd>';
       $output .= '<dt>' . t('Comment approval') . '</dt>';
-      $output .= '<dd>' . t("Comments from users who have the <em>Skip comment approval</em> permission are published immediately. All other comments are placed in the <a href='@comment-approval'>Unapproved comments</a> queue, until a user who has permission to <em>Administer comments</em> publishes or deletes them. Published comments can be bulk managed on the <a href='@admin-comment'>Published comments</a> administration page.", array('@comment-approval' => url('admin/content/comment/approval'), '@admin-comment' => url('admin/content/comment'))) . '</dd>';
+      $output .= '<dd>' . t("Comments from users who have the <em>Skip comment approval</em> permission are published immediately. All other comments are placed in the <a href='@comment-approval'>Unpublished comments</a> queue, until a user who has permission to <em>Administer comments</em> publishes or deletes them. Published comments can be bulk managed on the <a href='@admin-comment'>Published comments</a> administration page.", array('@comment-approval' => url('admin/content/comment/approval'), '@admin-comment' => url('admin/content/comment'))) . '</dd>';
       $output .= '</dl>';
       return $output;
   }
@@ -196,7 +196,7 @@ function comment_menu() {
     'type' => MENU_DEFAULT_LOCAL_TASK,
   );
   $items['admin/content/comment/approval'] = array(
-    'title' => 'Unapproved comments',
+    'title' => 'Unpublished comments',
     'title callback' => 'comment_count_unpublished',
     'page arguments' => array('approval'),
     'access arguments' => array('administer comments'),
@@ -217,10 +217,15 @@ function comment_menu() {
     'type' => MENU_LOCAL_TASK,
     'route_name' => 'comment_edit_page',
   );
-  $items['comment/%comment/approve'] = array(
-    'title' => 'Approve',
+  $items['comment/%comment/publish'] = array(
+    'title' => 'Publish',
     'weight' => 10,
-    'route_name' => 'comment_approve',
+    'route_name' => 'comment_publish',
+  );
+  $items['comment/%comment/unpublish'] = array(
+    'title' => 'Unpublish',
+    'weight' => 10,
+    'route_name' => 'comment_unpublish',
   );
   $items['comment/%comment/delete'] = array(
     'title' => 'Delete',
@@ -262,13 +267,13 @@ function comment_menu_alter(&$items) {
 }
 
 /**
- * Returns a menu title which includes the number of unapproved comments.
+ * Returns a menu title which includes the number of unpublished comments.
  */
 function comment_count_unpublished() {
   $count = db_query('SELECT COUNT(cid) FROM {comment} WHERE status = :status', array(
     ':status' => COMMENT_NOT_PUBLISHED,
   ))->fetchField();
-  return t('Unapproved comments (@count)', array('@count' => $count));
+  return t('Unpublished comments (@count)', array('@count' => $count));
 }
 
 /**
@@ -896,12 +901,20 @@ function comment_links(Comment $comment, EntityInterface $node) {
         'html' => TRUE,
       );
     }
-    if ($comment->status->value == COMMENT_NOT_PUBLISHED && $comment->access('approve')) {
-      $links['comment-approve'] = array(
-        'title' => t('approve'),
-        'href' => "comment/{$comment->id()}/approve",
+    if ($comment->status->value == COMMENT_NOT_PUBLISHED && $comment->access('publish')) {
+      $links['comment-publish'] = array(
+        'title' => t('publish'),
+        'href' => "comment/{$comment->id()}/publish",
+        'html' => TRUE,
+        'query' => array('token' => drupal_get_token("comment/{$comment->id()}/publish")),
+      );
+    }
+    if ($comment->status->value == COMMENT_PUBLISHED && $comment->access('unpublish')) {
+      $links['comment-unpublish'] = array(
+        'title' => t('unpublish'),
+        'href' => "comment/{$comment->id()}/unpublish",
         'html' => TRUE,
-        'query' => array('token' => drupal_get_token("comment/{$comment->id()}/approve")),
+        'query' => array('token' => drupal_get_token("comment/{$comment->id()}/unpublish")),
       );
     }
     if (empty($links)) {
diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml
index b62c118..84dc5c1 100644
--- a/core/modules/comment/comment.routing.yml
+++ b/core/modules/comment/comment.routing.yml
@@ -5,13 +5,21 @@ comment_edit_page:
   requirements:
     _entity_access: 'comment.update'
 
-comment_approve:
-  pattern: '/comment/{comment}/approve'
+comment_publish:
+  pattern: '/comment/{comment}/publish'
   defaults:
-    _content: '\Drupal\comment\Controller\CommentController::commentApprove'
+    _content: '\Drupal\comment\Controller\CommentController::commentPublish'
     entity_type: 'comment'
   requirements:
-    _entity_access: 'comment.approve'
+    _entity_access: 'comment.publish'
+
+comment_unpublish:
+  pattern: '/comment/{comment}/unpublish'
+  defaults:
+    _content: '\Drupal\comment\Controller\CommentController::commentUnpublish'
+    entity_type: 'comment'
+  requirements:
+    _entity_access: 'comment.unpublish'
 
 comment_permalink:
   pattern: '/comment/{comment}'
diff --git a/core/modules/comment/comment.views.inc b/core/modules/comment/comment.views.inc
index 66e2083..21643cf 100644
--- a/core/modules/comment/comment.views.inc
+++ b/core/modules/comment/comment.views.inc
@@ -229,17 +229,17 @@ function comment_views_data() {
   );
 
   $data['comment']['status'] = array(
-    'title' => t('Approved status'),
-    'help' => t('Whether the comment is approved (or still in the moderation queue).'),
+    'title' => t('Published status'),
+    'help' => t('Whether the comment is published (or still in the moderation queue).'),
     'field' => array(
       'id' => 'boolean',
       'output formats' => array(
-        'approved-not-approved' => array(t('Approved'), t('Not Approved')),
+        'published-not-publlished' => array(t('Published'), t('Not Published')),
       ),
     ),
     'filter' => array(
       'id' => 'boolean',
-      'label' => t('Approved comment status'),
+      'label' => t('Published comment status'),
       'type' => 'yes-no',
     ),
     'sort' => array(
diff --git a/core/modules/comment/lib/Drupal/comment/CommentAccessController.php b/core/modules/comment/lib/Drupal/comment/CommentAccessController.php
index 98e03e1..0e7ff22 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentAccessController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentAccessController.php
@@ -35,10 +35,13 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
         return user_access('administer comments', $account);
         break;
 
-      case 'approve':
+      case 'publish':
         return user_access('administer comments', $account);
         break;
-    }
+
+      case 'unpublish':
+        return user_access('administer comments', $account);
+        break;    }
   }
 
   /**
diff --git a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
index 84ef0c1..f95561f 100644
--- a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
+++ b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php
@@ -72,20 +72,51 @@ public static function create(ContainerInterface $container) {
    * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
    * @return \Symfony\Component\HttpFoundation\RedirectResponse.
    */
-  public function commentApprove(Request $request, CommentInterface $comment) {
+  public function commentPublish(Request $request, CommentInterface $comment) {
     // @todo CRSF tokens are validated in the content controller until it gets
     //   moved to the access layer:
     //   Integrate CSRF link token directly into routing system:
     //   https://drupal.org/node/1798296.
     $token = $request->query->get('token');
-    if (!isset($token) || !drupal_valid_token($token, 'comment/' . $comment->id() . '/approve')) {
+    if (!isset($token) || !drupal_valid_token($token, 'comment/' . $comment->id() . '/publish')) {
       throw new AccessDeniedHttpException();
     }
 
     $comment->status->value = COMMENT_PUBLISHED;
     $comment->save();
 
-    drupal_set_message(t('Comment approved.'));
+    drupal_set_message(t('Comment published.'));
+    $permalink_uri = $comment->permalink();
+    $permalink_uri['options']['absolute'] = TRUE;
+    $url = $this->urlGenerator->generateFromPath($permalink_uri['path'], $permalink_uri['options']);
+    return new RedirectResponse($url);
+  }
+
+  /**
+   * Unpublishes the specified comment.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\comment\CommentInterface $comment
+   *   A comment entity.
+   *
+   * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
+   * @return \Symfony\Component\HttpFoundation\RedirectResponse.
+   */
+  public function commentUnpublish(Request $request, CommentInterface $comment) {
+    // @todo CRSF tokens are validated in the content controller until it gets
+    //   moved to the access layer:
+    //   Integrate CSRF link token directly into routing system:
+    //   https://drupal.org/node/1798296.
+    $token = $request->query->get('token');
+    if (!isset($token) || !drupal_valid_token($token, 'comment/' . $comment->id() . '/unpublish')) {
+      throw new AccessDeniedHttpException();
+    }
+
+    $comment->status->value = COMMENT_NOT_PUBLISHED;
+    $comment->save();
+
+    drupal_set_message(t('Comment unpublished.'));
     $permalink_uri = $comment->permalink();
     $permalink_uri['options']['absolute'] = TRUE;
     $url = $this->urlGenerator->generateFromPath($permalink_uri['path'], $permalink_uri['options']);
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/LinkApprove.php b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/LinkApprove.php
index 118d502..4918b0b 100644
--- a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/LinkApprove.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/LinkApprove.php
@@ -32,12 +32,12 @@ function render_link($data, ResultRow $values) {
       return;
     }
 
-    $text = !empty($this->options['text']) ? $this->options['text'] : t('approve');
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('publish');
     $cid =  $this->getValue($values, 'cid');
 
     $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['path'] = "comment/" . $cid . "/approve";
-    $this->options['alter']['query'] = drupal_get_destination() + array('token' => drupal_get_token("comment/$cid/approve"));
+    $this->options['alter']['path'] = "comment/" . $cid . "/publish";
+    $this->options['alter']['query'] = drupal_get_destination() + array('token' => drupal_get_token("comment/$cid/publish"));
 
     return $text;
   }
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentApprovalTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentApprovalTest.php
index 6f70b0c..915efb0 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentApprovalTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentApprovalTest.php
@@ -64,16 +64,29 @@ function testApprovalAdminInterface() {
     $comments[] = $this->postComment($this->node, $this->randomName(), $this->randomName(), TRUE);
     $comments[] = $this->postComment($this->node, $this->randomName(), $this->randomName(), TRUE);
 
+    // Unpublish comment.
+    $this->drupalLogin($this->admin_user);
+    $this->drupalGet('comment/1/unpublish');
+    $this->assertResponse(403, 'Forged comment unpublish was denied.');
+    $this->drupalGet('comment/1/unpublish', array('query' => array('token' => 'forged')));
+    $this->assertResponse(403, 'Forged comment unpublish was denied.');
+    $this->drupalGet('node/' . $this->node->id());
+    $this->clickLink(t('unpublish'));
+    $this->drupalLogout();
+
+    $this->drupalGet('node/' . $this->node->id());
+    $this->assertFalse($this->commentExists($anonymous_comment4), 'Comment was unpublished.');
+
     // Publish multiple comments in one operation.
     $this->drupalLogin($this->admin_user);
     $this->drupalGet('admin/content/comment/approval');
-    $this->assertText(t('Unapproved comments (@count)', array('@count' => 2)), 'Two unapproved comments waiting for approval.');
+    $this->assertText(t('Unpublished comments (@count)', array('@count' => 2)), 'Two unpublished comments waiting for approval.');
     $edit = array(
       "comments[{$comments[0]->id()}]" => 1,
       "comments[{$comments[1]->id()}]" => 1,
     );
     $this->drupalPost(NULL, $edit, t('Update'));
-    $this->assertText(t('Unapproved comments (@count)', array('@count' => 0)), 'All comments were approved.');
+    $this->assertText(t('Unpublished comments (@count)', array('@count' => 0)), 'All comments were published.');
 
     // Delete multiple comments in one operation.
     $edit = array(
@@ -116,17 +129,30 @@ function testApprovalNodeInterface() {
 
     $this->assertFalse($this->commentExists($anonymous_comment4), 'Anonymous comment was not published.');
 
-    // Approve comment.
+    // Publish comment.
     $this->drupalLogin($this->admin_user);
-    $this->drupalGet('comment/1/approve');
+    $this->drupalGet('comment/1/publish');
     $this->assertResponse(403, 'Forged comment approval was denied.');
-    $this->drupalGet('comment/1/approve', array('query' => array('token' => 'forged')));
+    $this->drupalGet('comment/1/publish', array('query' => array('token' => 'forged')));
     $this->assertResponse(403, 'Forged comment approval was denied.');
     $this->drupalGet('node/' . $this->node->id());
-    $this->clickLink(t('approve'));
+    $this->clickLink(t('publish'));
     $this->drupalLogout();
 
     $this->drupalGet('node/' . $this->node->id());
     $this->assertTrue($this->commentExists($anonymous_comment4), 'Anonymous comment visible.');
+
+    // Unpublish comment.
+    $this->drupalLogin($this->admin_user);
+    $this->drupalGet('comment/1/unpublish');
+    $this->assertResponse(403, 'Forged comment unapproval was denied.');
+    $this->drupalGet('comment/1/unpublish', array('query' => array('token' => 'forged')));
+    $this->assertResponse(403, 'Forged comment unapproval was denied.');
+    $this->drupalGet('node/' . $this->node->id());
+    $this->clickLink(t('unpublish'));
+    $this->drupalLogout();
+
+    $this->drupalGet('node/' . $this->node->id());
+    $this->assertFalse($this->commentExists($anonymous_comment4), 'Comment was unpublished.');
   }
 }
