diff --git a/core/modules/ckeditor/ckeditor.admin.inc b/core/modules/ckeditor/ckeditor.admin.inc
index 3342e1b..ac81746 100644
--- a/core/modules/ckeditor/ckeditor.admin.inc
+++ b/core/modules/ckeditor/ckeditor.admin.inc
@@ -66,6 +66,9 @@ function theme_ckeditor_settings_toolbar($variables) {
       else {
         $data = '?';
       }
+      // Wrap the button to make it accessible.
+      $data = '<a href="#" role="button" aria-label="' . $button['label'] . '" aria-haspopup="true" aria-describedby="ckeditor-button-description">' . $data  . '</a>';
+
       $button_item = array(
         'data' => $data,
         'data-button-name' => $button_name,
@@ -90,6 +93,9 @@ function theme_ckeditor_settings_toolbar($variables) {
     else {
       $data = '?';
     }
+    // Wrap the button to make it accessible.
+    $data = '<a href="#" role="button" aria-label="' . $button['label'] . '" aria-haspopup="true">' . $data  . '</a>';
+
     $button_item = array(
       'data' => $data,
       'data-button-name' => $button_name,
@@ -110,6 +116,9 @@ function theme_ckeditor_settings_toolbar($variables) {
     else {
       $data = '?';
     }
+    // Wrap the button to make it accessible.
+    $data = '<a href="#" role="button" aria-label="' . $button['label'] . '" aria-haspopup="true">' . $data  . '</a>';
+
     $button_item = array(
       'data' => $data,
       'data-button-name' => $button_name,
@@ -124,10 +133,11 @@ function theme_ckeditor_settings_toolbar($variables) {
   // We don't use theme_item_list() below in case there are no buttons in the
   // active or disabled list, as theme_item_list() will not print an empty UL.
   $output = '';
-  $output .= '<strong>' . t('Active toolbar') . '</strong>';
+  $output .= '<label id="ckeditor-active-toolbar">' . t('Active toolbar') . '</label>';
+  $output .= '<p id="ckeditor-button-description">' . t('Toolbar buttons may be moved by drag and drop or with the keyboard arrow keys. Move a button up into the active toolbar to enable it, or down into the "Available buttons" list to disable it.') . '</p>';
   $output .= '<div class="ckeditor-toolbar-active clearfix">';
   foreach ($active_buttons as $button_row) {
-    $output .= '<ul class="ckeditor-buttons">';
+    $output .= '<ul class="ckeditor-buttons" aria-role="row" aria-labelledby="ckeditor-active-toolbar">';
     foreach ($button_row as $button) {
       $contents = $button['data'];
       unset($button['data']);
@@ -137,20 +147,20 @@ function theme_ckeditor_settings_toolbar($variables) {
     $output .= '</ul>';
   }
   if (empty($active_buttons)) {
-    $output .= '<ul class="ckeditor-buttons">';
+    $output .= '<ul class="ckeditor-buttons" aria-role="row" aria-labelledby="ckeditor-active-toolbar">';
     $output .= '</ul>';
   }
 
   $output .= '<div class="ckeditor-row-controls">';
-  $output .= '<a href="#" class="ckeditor-row-remove" title="' . t('Remove row') . '">-</a>';
-  $output .= '<a href="#" class="ckeditor-row-add" title="' . t('Add row') . '">+</a>';
+  $output .= '<a href="#" role="button" aria-label="' . t('Remove last button row') . '" class="ckeditor-row-remove" title="' . t('Remove row') . '">-</a>';
+  $output .= '<a href="#" role="button" aria-label="' . t('Add additional button row') . '" class="ckeditor-row-add" title="' . t('Add row') . '">+</a>';
   $output .= '</div>';
 
   $output .= '</div>';
 
-  $output .= '<strong>' . t('Available buttons') . '</strong>';
+  $output .= '<label id="ckeditor-available-buttons">' . t('Available buttons') . '</label>';
   $output .= '<div class="ckeditor-toolbar-disabled clearfix">';
-  $output .= '<ul class="ckeditor-buttons">';
+  $output .= '<ul class="ckeditor-buttons" aria-role="row" aria-labelledby="ckeditor-available-buttons">';
   foreach ($disabled_buttons as $button) {
     $contents = $button['data'];
     unset($button['data']);
@@ -159,7 +169,7 @@ function theme_ckeditor_settings_toolbar($variables) {
   }
   $output .= '</ul>';
   $output .= '<strong class="ckeditor-multiple-label">' . t('Dividers') . ': </strong>';
-  $output .= '<ul class="ckeditor-multiple-buttons">';
+  $output .= '<ul class="ckeditor-multiple-buttons" aria-labelledby="ckeditor-available-buttons">';
   foreach ($multiple_buttons as $button) {
     $contents = $button['data'];
     unset($button['data']);
diff --git a/core/modules/ckeditor/css/ckeditor.admin.css b/core/modules/ckeditor/css/ckeditor.admin.css
index 15fad3b..de51af7 100644
--- a/core/modules/ckeditor/css/ckeditor.admin.css
+++ b/core/modules/ckeditor/css/ckeditor.admin.css
@@ -29,8 +29,8 @@ ul.ckeditor-buttons {
   min-width: 26px;
   list-style: none;
 
-  float: left;
-  clear: left;
+  float: left; /* RTL */
+  clear: left; /* RTL */
   padding: 0;
   margin: 0 6px 5px 0;
   border: 1px solid #a6a6a6;
@@ -40,13 +40,21 @@ ul.ckeditor-buttons {
 }
 ul.ckeditor-buttons li {
   display: inline-block;
+  padding: 0;
+  margin: 0;
+  float: left; /* RTL */
+}
+ul.ckeditor-buttons li a {
+  position: relative;
+  display: inline-block;
   height: 18px;
   padding: 4px 6px;
-  outline: none;
   cursor: move;
-  float: left;
   border: 0;
   white-space: nowrap;
+  text-decoration: none;
+  text-shadow: 0 1px 0 rgba(255,255,255,.5);
+  color: #474747;
 
   background: #e4e4e4;
   background-image: -webkit-gradient(linear,left top,left bottom,from(white),to(#e4e4e4));
@@ -57,15 +65,18 @@ ul.ckeditor-buttons li {
   background-image: linear-gradient(top,white,#e4e4e4);
   filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffffff',endColorstr='#ffe4e4e4');
 }
-ul.ckeditor-buttons li:first-child {
-  border-top-left-radius: 2px;
-  border-bottom-left-radius: 2px;
+ul.ckeditor-buttons li a:focus {
+  z-index: 11; /* Ensure focused buttons show their outline on all sides. */
 }
-ul.ckeditor-buttons li:last-child {
-  border-top-right-radius: 2px;
-  border-bottom-right-radius: 2px;
+ul.ckeditor-buttons li:first-child a {
+  border-top-left-radius: 2px; /* RTL */
+  border-bottom-left-radius: 2px; /* RTL */
 }
-ul.ckeditor-buttons li.ckeditor-button-placeholder {
+ul.ckeditor-buttons li:last-child a {
+  border-top-right-radius: 2px; /* RTL */
+  border-bottom-right-radius: 2px; /* RTL */
+}
+ul.ckeditor-buttons li.ckeditor-button-placeholder a {
   background: #333;
   opacity: 0.3;
 }
@@ -73,31 +84,39 @@ ul.ckeditor-multiple-buttons {
   padding: 2px;
   margin: 0;
   list-style: none;
-  float: left;
+  float: left; /* RTL */
 }
 ul.ckeditor-multiple-buttons li {
-  padding: 2px 0;
+  display: inline-block;
+  padding: 0;
   margin: 0;
+  float: left; /* RTL */
+}
+ul.ckeditor-multiple-buttons li a {
   display: inline-block;
+  padding: 2px 0;
+  margin: 0;
   height: 18px;
   cursor: move;
-  float: left;
 }
 .ckeditor-multiple-label {
-  float: left;
+  float: left; /* RTL */
   padding: 4px;
 }
 ul.ckeditor-buttons li.ckeditor-group-button-separator,
 ul.ckeditor-multiple-buttons li.ckeditor-group-button-separator {
+  margin: -1px -3px -2px;
+}
+ul.ckeditor-buttons li.ckeditor-group-button-separator a,
+ul.ckeditor-multiple-buttons li.ckeditor-group-button-separator a {
   background: url(../images/group-separator.png) no-repeat center center;
   width: 13px;
   padding: 0;
   height: 29px;
-  margin: -1px -3px -2px;
   position: relative;
   z-index: 10;
 }
-ul.ckeditor-buttons li.ckeditor-button-separator {
+ul.ckeditor-buttons li.ckeditor-button-separator a {
   width: 2px;
   padding: 0 4px;
   height: 26px;
@@ -114,7 +133,7 @@ ul.ckeditor-buttons li.ckeditor-button-separator {
   background-image: linear-gradient(top, white, #e4e4e4);
   filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#ffffffff', endColorstr='#ffe4e4e4');
 }
-ul.ckeditor-multiple-buttons li.ckeditor-button-separator {
+ul.ckeditor-multiple-buttons li.ckeditor-button-separator a {
   width: 2px;
   padding: 0;
   height: 26px;
@@ -142,10 +161,10 @@ ul.ckeditor-multiple-buttons li.ckeditor-button-separator {
 }
 
 .ckeditor-row-controls {
-  float: right;
+  float: right; /* RTL */
   font-size: 18px;
   width: 40px;
-  text-align: right;
+  text-align: right; /* RTL */
 }
 .ckeditor-row-controls a {
   display: inline-block;
diff --git a/core/modules/ckeditor/js/ckeditor.admin.js b/core/modules/ckeditor/js/ckeditor.admin.js
index d22ac6e..4d58157 100644
--- a/core/modules/ckeditor/js/ckeditor.admin.js
+++ b/core/modules/ckeditor/js/ckeditor.admin.js
@@ -20,11 +20,29 @@ Drupal.behaviors.ckeditorAdmin = {
         cursor: 'move',
         stop: adminToolbarValue
       };
-      $toolbarAdmin.insertAfter($textareaWrapper).find('.ckeditor-buttons').sortable(sortableSettings);
+      // Add the toolbar to the page.
+      $toolbarAdmin.insertAfter($textareaWrapper);
+
+      // Then determine if this is RTL or not.
+      var rtl = $toolbarAdmin.css('direction') === 'rtl' ? -1 : 1;
+      var $toolbarRows = $toolbarAdmin.find('.ckeditor-buttons');
+
+      // Add the drag and drop functionality.
+      $toolbarRows.sortable(sortableSettings);
       $toolbarAdmin.find('.ckeditor-multiple-buttons li').draggable({
         connectToSortable: '.ckeditor-toolbar-active .ckeditor-buttons',
         helper: 'clone'
       });
+
+      // Add keyboard arrow support.
+      $toolbarAdmin.on('keyup.ckeditorMoveButton', '.ckeditor-buttons a', adminToolbarMoveButton);
+      $toolbarAdmin.on('keyup.ckeditorMoveSeparator', '.ckeditor-multiple-buttons a', adminToolbarMoveSeparator);
+
+      // Add click for help.
+      $toolbarAdmin.on('click.ckeditorClickButton', '.ckeditor-buttons a', { type: 'button' }, adminToolbarButtonHelp);
+      $toolbarAdmin.on('click.ckeditorClickSeparator', '.ckeditor-multiple-buttons a', { type: 'separator' }, adminToolbarButtonHelp);
+
+      // Add/remove row button functionality.
       $toolbarAdmin.on('click.ckeditorAddRow', 'a.ckeditor-row-add', adminToolbarAddRow);
       $toolbarAdmin.on('click.ckeditorAddRow', 'a.ckeditor-row-remove', adminToolbarRemoveRow);
       if ($toolbarAdmin.find('.ckeditor-toolbar-active ul').length > 1) {
@@ -32,12 +50,104 @@ Drupal.behaviors.ckeditorAdmin = {
       }
 
       /**
+       * Event callback for keypress. Move buttons based on arrow keys.
+       */
+      function adminToolbarMoveButton(event) {
+        var $button = $(this).parent();
+        var $currentRow = $button.closest('.ckeditor-buttons');
+        var $destinationRow = null;
+        var destinationPosition = $button.index();
+
+        switch (event.keyCode) {
+          case 37: // Left arrow.
+          case 63234: // Safari left arrow.
+            $destinationRow = $currentRow;
+            destinationPosition = destinationPosition - (1 * rtl);
+            break;
+          case 38: // Up arrow.
+          case 63232: // Safari up arrow.
+          console.log($toolbarRows);
+            $destinationRow = $($toolbarRows[$toolbarRows.index($currentRow) - 1]);
+            break;
+          case 39: // Right arrow.
+          case 63235: // Safari right arrow.
+            $destinationRow = $currentRow;
+            destinationPosition = destinationPosition + (1 * rtl);
+            break;
+          case 40: // Down arrow.
+          case 63233: // Safari down arrow.
+            $destinationRow = $($toolbarRows[$toolbarRows.index($currentRow) + 1]);
+        }
+
+        if ($destinationRow && $destinationRow.length) {
+          // Detach the button from the DOM so its position doesn't interfere.
+          $button.detach();
+          // Move the button before the button whose position it should occupy.
+          var $targetButton = $destinationRow.children(':eq(' + destinationPosition + ')');
+          if ($targetButton.length) {
+            $targetButton.before($button);
+          }
+          else {
+            $destinationRow.append($button);
+          }
+          // Update the toolbar value field.
+          adminToolbarValue(event, { item: $button });
+        }
+        event.preventDefault();
+      }
+
+      /**
+       * Event callback for keyup. Move a separator into the active toolbar.
+       */
+      function adminToolbarMoveSeparator(event) {
+        switch (event.keyCode) {
+          case 38: // Up arrow.
+          case 63232: // Safari up arrow.
+            var $button = $(this).parent().clone().appendTo($toolbarRows.eq(-2));
+            adminToolbarValue(event, { item: $button });
+            event.preventDefault();
+        }
+      }
+
+      /**
+       * Provide help when a button is clicked on.
+       */
+      function adminToolbarButtonHelp(event) {
+        var $link = $(this);
+        var $button = $link.parent();
+        var $currentRow = $button.closest('.ckeditor-buttons');
+        var enabled = $button.closest('.ckeditor-toolbar-active').length > 0;
+        var position = $button.index() + 1; // 1-based index for humans.
+        var rowNumber = $toolbarRows.index($currentRow) + 1;
+        var type = event.data.type;
+        if (enabled) {
+          if (type === 'separator') {
+            alert(Drupal.t('Separators are used to visually split individual buttons. This "@name" is currently enabled, in row @row and position @position.', { '@name': $link.attr('aria-label'), '@row': rowNumber, '@position': position }) + "\n\n" + Drupal.t('Drag and drop the separator or use the keyboard arrow keys to change the position of this separator.'));
+          }
+          else {
+            alert(Drupal.t('The "@name" button is currently enabled, in row @row and position @position.', { '@name': $link.attr('aria-label'), '@row': rowNumber, '@position': position }) + "\n\n" + Drupal.t('Drag and drop the buttons or use the keyboard arrow keys to change the position of this button.'));
+          }
+        }
+        else {
+          if (type === 'separator') {
+            alert(Drupal.t('Separators are used to visually split individual buttons. This "@name" is currently disabled.', { '@name': $link.attr('aria-label') }) + "\n\n" + Drupal.t('Drag the button or use the up arrow key to move this separator into the active toolbar. You may add multiple separators to each row.'));
+          }
+          else {
+            alert(Drupal.t('The "@name" button is currently disabled.', { '@name': $link.attr('aria-label') }) + "\n\n" + Drupal.t('Drag the button or use the up arrow key to move this button into the active toolbar.'));
+          }
+        }
+        $link.focus();
+        event.preventDefault();
+      }
+
+      /**
        * Add a new row of buttons.
        */
       function adminToolbarAddRow(event) {
         var $this = $(this);
         var $rows = $this.closest('.ckeditor-toolbar-active').find('.ckeditor-buttons');
         $rows.last().clone().empty().insertAfter($rows.last()).sortable(sortableSettings);
+        $toolbarRows = $toolbarAdmin.find('.ckeditor-buttons');
         $this.siblings('a').show();
         redrawToolbarGradient();
         event.preventDefault();
@@ -57,6 +167,7 @@ Drupal.behaviors.ckeditorAdmin = {
           var $disabledButtons = $wrapper.find('.ckeditor-toolbar-disabled .ckeditor-buttons');
           $lastRow.children(':not(.ckeditor-multiple-button)').prependTo($disabledButtons);
           $lastRow.sortable('destroy').remove();
+          $toolbarRows = $toolbarAdmin.find('.ckeditor-buttons');
           redrawToolbarGradient();
         }
         event.preventDefault();
@@ -78,6 +189,8 @@ Drupal.behaviors.ckeditorAdmin = {
       function adminToolbarValue(event, ui) {
         // Update the toolbar config after updating a sortable.
         var toolbarConfig = [];
+        var $button = ui.item;
+        $button.find('a').focus();
         $wrapper.find('.ckeditor-toolbar-active ul').each(function() {
           var $rowButtons = $(this).find('li');
           var rowConfig = [];
