diff --git a/common/scintilla_tricks.cpp b/common/scintilla_tricks.cpp
index fdeab3fbe0..c3bf8798fd 100644
--- a/common/scintilla_tricks.cpp
+++ b/common/scintilla_tricks.cpp
@@ -24,6 +24,7 @@
 
 #include <string_utils.h>
 #include <scintilla_tricks.h>
+#include <widgets/wx_grid.h>
 #include <wx/stc/stc.h>
 #include <gal/color4d.h>
 #include <dialog_shim.h>
@@ -255,6 +256,11 @@ void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
     }
     else if( aEvent.GetKeyCode() == WXK_TAB )
     {
+        wxWindow* ancestor = m_te->GetParent();
+
+        while( ancestor && !dynamic_cast<WX_GRID*>( ancestor ) )
+            ancestor = ancestor->GetParent();
+
         if( aEvent.ControlDown() )
         {
             int flags = 0;
@@ -270,6 +276,47 @@ void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
             if( parent )
                 parent->NavigateIn( flags );
         }
+        else if( dynamic_cast<WX_GRID*>( ancestor ) )
+        {
+            WX_GRID* grid = static_cast<WX_GRID*>( ancestor );
+            int      row = grid->GetGridCursorRow();
+            int      col = grid->GetGridCursorCol();
+
+            if( aEvent.ShiftDown() )
+            {
+                if( col > 0 )
+                {
+                    col--;
+                }
+                else if( row > 0 )
+                {
+                    col = (int) grid->GetNumberCols() - 1;
+
+                    if( row > 0 )
+                        row--;
+                    else
+                        row = (int) grid->GetNumberRows() - 1;
+                }
+            }
+            else
+            {
+                if( col < (int) grid->GetNumberCols() - 1 )
+                {
+                    col++;
+                }
+                else if( row < grid->GetNumberRows() - 1 )
+                {
+                    col = 0;
+
+                    if( row < grid->GetNumberRows() - 1 )
+                        row++;
+                    else
+                        row = 0;
+                }
+            }
+
+            grid->SetGridCursor( row, col );
+        }
         else
         {
             m_te->Tab();
diff --git a/pcbnew/dialogs/dialog_table_properties.cpp b/pcbnew/dialogs/dialog_table_properties.cpp
index 2302ae6f05..fab94425d4 100644
--- a/pcbnew/dialogs/dialog_table_properties.cpp
+++ b/pcbnew/dialogs/dialog_table_properties.cpp
@@ -159,7 +159,12 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataToWindow()
     {
         for( int col = 0; col < m_table->GetColCount(); ++col )
         {
-            PCB_TABLECELL* tableCell = m_table->GetCell( row, col );
+            PCB_TABLECELL* tableCell;
+
+            if( IsBackLayer( m_table->GetLayer() ) )
+                tableCell = m_table->GetCell( row, m_table->GetColCount() - 1 - col );
+            else
+                tableCell = m_table->GetCell( row, col );
 
             if( tableCell->GetColSpan() == 0 || tableCell->GetRowSpan() == 0 )
                 m_grid->SetCellValue( row, col, coveredColor.GetAsString() );
@@ -292,8 +297,14 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataFromWindow()
     {
         for( int col = 0; col < m_table->GetColCount(); ++col )
         {
-            PCB_TABLECELL* tableCell = m_table->GetCell( row, col );
-            wxString       txt = m_grid->GetCellValue( row, col );
+            PCB_TABLECELL* tableCell;
+
+            if( IsBackLayer( m_table->GetLayer() ) )
+                tableCell = m_table->GetCell( row, m_table->GetColCount() - 1 - col );
+            else
+                tableCell = m_table->GetCell( row, col );
+
+            wxString txt = m_grid->GetCellValue( row, col );
 
 #ifdef __WXMAC__
             // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp
index 570f956ef3..6dcab5b2e2 100644
--- a/pcbnew/edit.cpp
+++ b/pcbnew/edit.cpp
@@ -46,6 +46,7 @@
 #include <tools/pcb_actions.h>
 #include <tools/drc_tool.h>
 #include <dialogs/dialog_dimension_properties.h>
+#include <dialogs/dialog_table_properties.h>
 #include <pcb_layer_box_selector.h>
 
 // Handles the selection of command events.
@@ -137,6 +138,13 @@ void PCB_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem )
         ShowTextBoxPropertiesDialog( static_cast<PCB_TEXTBOX*>( aItem ) );
         break;
 
+    case PCB_TABLE_T:
+    {
+        DIALOG_TABLE_PROPERTIES dlg( this, static_cast<PCB_TABLE*>( aItem ) );
+        dlg.ShowQuasiModal();   // Scintilla's auto-complete requires quasiModal
+        break;
+    }
+
     case PCB_PAD_T:
         ShowPadPropertiesDialog( static_cast<PAD*>( aItem ) );
         break;
diff --git a/pcbnew/pcb_table.cpp b/pcbnew/pcb_table.cpp
index 42e42836ac..5177c1e871 100644
--- a/pcbnew/pcb_table.cpp
+++ b/pcbnew/pcb_table.cpp
@@ -189,6 +189,20 @@ void PCB_TABLE::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
 {
     for( PCB_TABLECELL* cell : m_cells )
         cell->Flip( aCentre, aFlipLeftRight );
+
+    std::vector<PCB_TABLECELL*> oldCells = m_cells;
+    int                         rowOffset = 0;
+
+    for( int row = 0; row < GetRowCount(); ++row )
+    {
+        for( int col = 0; col < GetColCount(); ++col )
+            m_cells[ rowOffset + col ] = oldCells[ rowOffset + GetColCount() - 1 - col ];
+
+        rowOffset += GetColCount();
+    }
+
+    SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
+    Normalize();
 }
 
 
diff --git a/pcbnew/pcb_tablecell.cpp b/pcbnew/pcb_tablecell.cpp
index 0754b3429b..5a134e2a3f 100644
--- a/pcbnew/pcb_tablecell.cpp
+++ b/pcbnew/pcb_tablecell.cpp
@@ -34,6 +34,8 @@ PCB_TABLECELL::PCB_TABLECELL( BOARD_ITEM* aParent ) :
         m_colSpan( 1 ),
         m_rowSpan( 1 )
 {
+    if( IsBackLayer( aParent->GetLayer() ) )
+        SetMirrored( true );
 }
 
 
diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp
index c3717a5269..99dab48f1b 100644
--- a/pcbnew/tools/drawing_tool.cpp
+++ b/pcbnew/tools/drawing_tool.cpp
@@ -25,6 +25,7 @@
 
 #include "drawing_tool.h"
 #include "geometry/shape_rect.h"
+#include "dialog_table_properties.h"
 
 #include <pgm_base.h>
 #include <settings/settings_manager.h>
@@ -1135,43 +1136,53 @@ int DRAWING_TOOL::DrawTable( const TOOL_EVENT& aEvent )
         {
             if( !table )
             {
-            m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
+                m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
 
-            PCB_LAYER_ID layer = m_frame->GetActiveLayer();
+                PCB_LAYER_ID layer = m_frame->GetActiveLayer();
 
-            table = new PCB_TABLE( m_frame->GetModel(), bds.GetLineThickness( layer ) );
-            table->SetColCount( 1 );
-            table->AddCell( new PCB_TABLECELL( table ) );
+                table = new PCB_TABLE( m_frame->GetModel(), bds.GetLineThickness( layer ) );
+                table->SetLayer( layer );
+                table->SetColCount( 1 );
+                table->AddCell( new PCB_TABLECELL( table ) );
 
-            table->SetLayer( layer );
-            table->SetPosition( cursorPos );
+                table->SetLayer( layer );
+                table->SetPosition( cursorPos );
 
-            if( !m_view->IsLayerVisible( layer ) )
-            {
-                m_frame->GetAppearancePanel()->SetLayerVisible( layer, true );
-                m_frame->GetCanvas()->Refresh();
-            }
+                if( !m_view->IsLayerVisible( layer ) )
+                {
+                    m_frame->GetAppearancePanel()->SetLayerVisible( layer, true );
+                    m_frame->GetCanvas()->Refresh();
+                }
 
-            m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, table );
-            m_view->Update( &selection() );
+                m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, table );
+                m_view->Update( &selection() );
 
-            // update the cursor so it looks correct before another event
-            setCursor();
+                // update the cursor so it looks correct before another event
+                setCursor();
             }
             else
             {
                 table->ClearFlags();
-                m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
-
                 table->Normalize();
 
-                commit.Add( table, m_frame->GetScreen() );
-                commit.Push( _( "Draw Table" ) );
+                DIALOG_TABLE_PROPERTIES dlg( m_frame, table );
+
+                if( dlg.ShowQuasiModal() == wxID_OK )
+                {
+                    m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
+
+                    commit.Add( table, m_frame->GetScreen() );
+                    commit.Push( _( "Draw Table" ) );
+
+                    m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, table );
+                    m_toolMgr->PostAction( ACTIONS::activatePointEditor );
+                }
+                else
+                {
+                    delete table;
+                }
 
-                m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, table );
                 table = nullptr;
-
-                m_toolMgr->PostAction( ACTIONS::activatePointEditor );
             }
         }
         else if( table && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )