diff --git a/web/pgadmin/misc/sql/__init__.py b/web/pgadmin/misc/sql/__init__.py
index 3a13bd84a..0906dd018 100644
--- a/web/pgadmin/misc/sql/__init__.py
+++ b/web/pgadmin/misc/sql/__init__.py
@@ -9,8 +9,12 @@
 
 """A blueprint module providing utility functions for the application."""
 
-from flask import url_for
+import sqlparse
+from flask import request, url_for
+from flask_security import login_required
 from pgadmin.utils import PgAdminModule
+from pgadmin.utils.ajax import make_json_response
+from pgadmin.utils.preferences import Preferences
 
 MODULE_NAME = 'sql'
 
@@ -24,5 +28,62 @@ class SQLModule(PgAdminModule):
         }]
 
 
+    def get_exposed_url_endpoints(self):
+        """
+        Returns:
+            list: URL endpoints
+        """
+        return [
+            'sql.format', 'sql.format'
+        ]
+
+
 # Initialise the module
 blueprint = SQLModule(MODULE_NAME, __name__, url_prefix='/misc/sql')
+
+
+def sql_format(sql):
+    """
+    This function takes a SQL statement, formats it, and returns it
+    """
+    p = Preferences.module('sqleditor')
+    output = sqlparse.format(sql,
+                           keyword_case=p.preference(
+                               'keyword_case').get(),
+                           identifier_case=p.preference(
+                               'identifier_case').get(),
+                           strip_comments=p.preference(
+                               'strip_comments').get(),
+                           reindent=p.preference(
+                               'reindent').get(),
+                           reindent_aligned=p.preference(
+                               'reindent_aligned').get(),
+                           use_space_around_operators=p.preference(
+                               'spaces_around_operators').get(),
+                           comma_first=p.preference(
+                               'comma_first').get(),
+                           wrap_after=p.preference(
+                               'wrap_after').get(),
+                           indent_tabs=not p.preference(
+                               'use_spaces').get(),
+                           indent_width=p.preference(
+                               'tab_size').get())
+
+    return output
+
+
+@blueprint.route("/format", methods=['POST'], endpoint="format")
+@login_required
+def sql_format_wrapper():
+    """
+    This endpoint takes a SQL statement, formats it, and returns it
+    """
+    sql = ''
+    if request.data:
+        sql = sql_format(request.get_json()['sql'])
+
+    return make_json_response(
+        data={'sql': sql},
+        status=200
+    )
+
diff --git a/web/pgadmin/static/js/keyboard_shortcuts.js b/web/pgadmin/static/js/keyboard_shortcuts.js
index 0a17ec133..c021d1830 100644
--- a/web/pgadmin/static/js/keyboard_shortcuts.js
+++ b/web/pgadmin/static/js/keyboard_shortcuts.js
@@ -17,7 +17,8 @@ const PERIOD_KEY = 190,
   LEFT_KEY = 37,
   UP_KEY = 38,
   RIGHT_KEY = 39,
-  DOWN_KEY = 40;
+  DOWN_KEY = 40,
+  K_KEY = 75;
 
 function isMac() {
   return window.navigator.platform.search('Mac') != -1;
@@ -247,6 +248,12 @@ function keyboardShortcutsQueryTool(
   ) && keyCode === PERIOD_KEY) {
     this._stopEventPropagation(event);
     queryToolActions.uncommentLineCode(sqlEditorController);
+  } else if ((
+    (this.isMac() && event.metaKey) ||
+     (!this.isMac() && event.ctrlKey)
+  ) && !event.altKey && event.shiftKey && keyCode === K_KEY) {
+    this._stopEventPropagation(event);
+    queryToolActions.formatSql(sqlEditorController);
   }  else if (keyCode == ESC_KEY) {
     queryToolActions.focusOut(sqlEditorController);
     /*Apply only for sub-dropdown*/
diff --git a/web/pgadmin/static/js/sqleditor/query_tool_actions.js b/web/pgadmin/static/js/sqleditor/query_tool_actions.js
index a29e0f507..a97582e6a 100644
--- a/web/pgadmin/static/js/sqleditor/query_tool_actions.js
+++ b/web/pgadmin/static/js/sqleditor/query_tool_actions.js
@@ -123,6 +123,10 @@ let queryToolActions = {
     );
   },
 
+  formatSql: function (sqlEditorController) {
+    sqlEditorController.gridView.on_format_sql();
+  },
+
   focusOut: function () {
     document.activeElement.blur();
     pgWindow.document.activeElement.blur();
diff --git a/web/pgadmin/tools/datagrid/templates/datagrid/index.html b/web/pgadmin/tools/datagrid/templates/datagrid/index.html
index 88b3c55b5..a7b6629b2 100644
--- a/web/pgadmin/tools/datagrid/templates/datagrid/index.html
+++ b/web/pgadmin/tools/datagrid/templates/datagrid/index.html
@@ -189,6 +189,15 @@
                                  {{ _(' (Shift+Ctrl+/)') }}{%- endif %}</span>
                         </a>
                     </li>
+                    <li class="dropdown-divider"></li>
+                    <li>
+                        <a class="dropdown-item" id="btn-format-sql" href="#" tabindex="0">
+                            <span>{{ _('Format SQL') }}{% if client_platform == 'macos' -%}
+                                 {{ _(' (Shift+Cmd+K)') }}
+                            {% else %}
+                                 {{ _(' (Shift+Ctrl+K)') }}{%- endif %}</span>
+                        </a>
+                    </li>
                 </ul>
             </div>
             <div class="btn-group mr-1" role="group" aria-label="">
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
index b2081b97e..b0bcdb913 100644
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
@@ -140,6 +140,9 @@ define('tools.querytool', [
       // Indentation options
       'click #btn-indent-code': 'on_indent_code',
       'click #btn-unindent-code': 'on_unindent_code',
+      // Format
+      'click #btn-format-sql': 'on_format_sql',
+      // Transaction control
       'click #btn-commit': 'on_commit_transaction',
       'click #btn-rollback': 'on_rollback_transaction',
     },
@@ -1743,6 +1746,16 @@ define('tools.querytool', [
       );
     },
 
+    on_format_sql: function() {
+      var self = this;
+      // Trigger the format signal to the SqlEditorController class
+      self.handler.trigger(
+        'pgadmin-sqleditor:format_sql',
+        self,
+        self.handler
+      );
+    },
+
     // Callback function for the clear button click.
     on_clear: function(ev) {
       var self = this;
@@ -2401,6 +2414,8 @@ define('tools.querytool', [
         // Indentation related
         self.on('pgadmin-sqleditor:indent_selected_code', self._indent_selected_code, self);
         self.on('pgadmin-sqleditor:unindent_selected_code', self._unindent_selected_code, self);
+        // Format
+        self.on('pgadmin-sqleditor:format_sql', self._format_sql, self);
 
         window.parent.$(window.parent.document).on('pgadmin-sqleditor:rows-copied', self._copied_in_other_session);
       },
@@ -4235,6 +4250,41 @@ define('tools.querytool', [
         editor.execCommand('indentLess');
       },
 
+      /*
+       * This function will format the SQL
+       */
+      _format_sql: function() {
+        var self = this,
+          editor = self.gridView.query_tool_obj,
+          selection = true,
+          sql = '';
+
+        sql = editor.getSelection();
+
+        if (sql == '') {
+          sql = editor.getValue();
+          selection = false;
+        }
+
+        $.ajax({
+          url: url_for('sql.format'),
+          data: JSON.stringify({'sql': sql}),
+          method: 'POST',
+          contentType: 'application/json',
+          dataType: 'json',
+        })
+          .done(function(res) {
+            if (selection === true) {
+              editor.replaceSelection(res.data.sql, 'around');
+            } else {
+              editor.setValue(res.data.sql);
+            }
+          })
+          .fail(function() {
+          /* failure should be ignored */
+          });
+      },
+
       isQueryRunning: function() {
         return is_query_running;
       },
diff --git a/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py b/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py
index b70e22102..70e3d8d84 100644
--- a/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py
+++ b/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py
@@ -169,27 +169,6 @@ def register_query_tool_preferences(self):
         )
     )
 
-    self.tab_size = self.preference.register(
-        'Editor', 'tab_size',
-        gettext("Tab size"), 'integer', 4,
-        min_val=2,
-        max_val=8,
-        category_label=gettext('Options'),
-        help_str=gettext(
-            'The number of spaces per tab. Minimum 2, maximum 8.'
-        )
-    )
-
-    self.use_spaces = self.preference.register(
-        'Editor', 'use_spaces',
-        gettext("Use spaces?"), 'boolean', False,
-        category_label=gettext('Options'),
-        help_str=gettext(
-            'Specifies whether or not to insert spaces instead of tabs '
-            'when the tab key or auto-indent are used.'
-        )
-    )
-
     self.wrap_code = self.preference.register(
         'Editor', 'wrap_code',
         gettext("Line wrapping?"), 'boolean', False,
@@ -703,3 +682,98 @@ def register_query_tool_preferences(self):
         category_label=gettext('Keyboard shortcuts'),
         fields=shortcut_fields
     )
+
+    # Register options for SQL formatting
+    self.keyword_case = self.preference.register(
+        'editor', 'keyword_case',
+        gettext("Keyword case"), 'radioModern', 'upper',
+        options=[{'label': 'Upper case', 'value': 'upper'},
+                 {'label': 'Lower case', 'value': 'lower'},
+                 {'label': 'Capitalized', 'value': 'capitalize'}],
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext(
+            'Convert keywords to upper, lower, or capitalized casing.'
+        )
+    )
+
+    self.identifier_case = self.preference.register(
+        'editor', 'identifier_case',
+        gettext("Identifier case"), 'radioModern', 'upper',
+        options=[{'label': 'Upper case', 'value': 'upper'},
+                 {'label': 'Lower case', 'value': 'lower'},
+                 {'label': 'Capitalized', 'value': 'capitalize'}],
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext(
+            'Convert identifiers to upper, lower, or capitalized casing.'
+        )
+    )
+
+    self.strip_comments = self.preference.register(
+        'editor', 'strip_comments',
+        gettext("Strip comments?"), 'boolean', False,
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext('If set to True, comments will be removed.')
+    )
+
+    self.reindent = self.preference.register(
+        'editor', 'reindent',
+        gettext("Re-indent?"), 'boolean', True,
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext('If set to True, the indentations of the '
+                         'statements are changed.')
+    )
+
+    self.reindent_aligned = self.preference.register(
+        'editor', 'reindent_aligned',
+        gettext("Re-indent aligned?"), 'boolean', False,
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext('If set to True, the indentations of the '
+                         'statements are changed, and statements are '
+                         'aligned by keywords.')
+    )
+
+    self.spaces_around_operators = self.preference.register(
+        'editor', 'spaces_around_operators',
+        gettext("Spaces around operators?"), 'boolean', True,
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext('If set to True, spaces are used around all '
+                         'operators.')
+    )
+
+    self.comma_first = self.preference.register(
+        'editor', 'comma_first',
+        gettext("Comma-first notation?"), 'boolean', False,
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext('If set to True, comma-first notation for column '
+                         'names is used.')
+    )
+
+    self.wrap_after = self.preference.register(
+        'editor', 'wrap_after',
+        gettext("Wrap after N characters"), 'integer', 4,
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext("The column limit (in characters) for wrapping "
+                         "comma-separated lists. If zero, it puts "
+                         "every item in the list on its own line.")
+    )
+
+    self.tab_size = self.preference.register(
+        'editor', 'tab_size',
+        gettext("Tab size"), 'integer', 4,
+        min_val=2,
+        max_val=8,
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext(
+            'The number of spaces per tab. Minimum 2, maximum 8.'
+        )
+    )
+
+    self.use_spaces = self.preference.register(
+        'editor', 'use_spaces',
+        gettext("Use spaces?"), 'boolean', False,
+        category_label=gettext('SQL Formatting'),
+        help_str=gettext(
+            'Specifies whether or not to insert spaces instead of tabs '
+            'when the tab key or auto-indent are used.'
+        )
+    )
