diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js
index ed96c21e9..0a44e7958 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js
@@ -12,8 +12,9 @@ import PrimaryKeySchema from './primary_key.ui';
 
 define('pgadmin.node.primary_key', [
   'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
-  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
-], function(gettext, url_for, $, _, pgAdmin, pgBrowser) {
+  'sources/pgadmin', 'pgadmin.browser', 'pgadmin.backform', 'pgadmin.backgrid',
+  'pgadmin.browser.collection',
+], function(gettext, url_for, $, _, pgAdmin, pgBrowser, Backform, Backgrid) {
 
   // Extend the browser's node class for index constraint node
   if (!pgBrowser.Nodes['primary_key']) {
@@ -107,6 +108,572 @@ define('pgadmin.node.primary_key', [
           index: ()=>getNodeListByName('index', treeNodeInfo, itemNodeData),
         }, treeNodeInfo);
       },
+      // Define the model for index constraint node
+      model: pgAdmin.Browser.Node.Model.extend({
+        idAttribute: 'oid',
+
+        defaults: {
+          name: undefined,
+          oid: undefined,
+          is_sys_obj: undefined,
+          comment: undefined,
+          spcname: undefined,
+          index: undefined,
+          fillfactor: undefined,
+          condeferrable: undefined,
+          condeferred: undefined,
+          columns: [],
+          include: [],
+        },
+
+        // Define the schema for the index constraint node
+        schema: [{
+          id: 'name', label: gettext('Name'), type: 'text',
+          mode: ['properties', 'create', 'edit'], editable:true,
+          cellHeaderClasses:'width_percent_40',
+        },{
+          id: 'oid', label: gettext('OID'), cell: 'string',
+          type: 'text' , mode: ['properties'], editable: false,
+          cellHeaderClasses:'width_percent_20',
+        },{
+          id: 'is_sys_obj', label: gettext('System primary key?'),
+          cell:'boolean', type: 'switch', mode: ['properties'],
+        },{
+          id: 'comment', label: gettext('Comment'), cell: 'string',
+          type: 'multiline', mode: ['properties', 'create', 'edit'],
+          deps:['name'], disabled:function(m) {
+            var name = m.get('name');
+            if (!(name && name != '')) {
+              setTimeout(function(){
+                if(m.get('comment') && m.get('comment') !== '') {
+                  m.set('comment', null);
+                }
+              },10);
+              return true;
+            } else {
+              return false;
+            }
+          },
+        },{
+          id: 'columns', label: gettext('Columns'),
+          type: 'collection', group: gettext('Definition'),
+          editable: false,
+          cell: Backgrid.StringCell.extend({
+            initialize: function() {
+              Backgrid.StringCell.prototype.initialize.apply(this, arguments);
+
+              var self = this,
+                collection = this.model.get('columns');
+
+              // Do not listen for any event(s) for existing constraint.
+              if (_.isUndefined(self.model.get('oid'))) {
+                var tableCols = self.model.top.get('columns');
+                self.listenTo(tableCols, 'remove' , self.removeColumn);
+                self.listenTo(tableCols, 'change:name', self.resetColOptions);
+              }
+
+              collection.on('pgadmin:multicolumn:updated', function() {
+                self.render.apply(self);
+              });
+              self.listenTo(collection, 'add', self.render);
+              self.listenTo(collection, 'remove', self.render);
+            },
+            removeColumn: function(m) {
+              var self = this,
+                removedCols = self.model.get('columns').where(
+                  {column: m.get('name')}
+                );
+
+              self.model.get('columns').remove(removedCols);
+              setTimeout(function () {
+                self.render();
+              }, 10);
+
+              var key = 'primary_key';
+              setTimeout(function () {
+                var constraints = self.model.top.get(key),
+                  removed = [];
+                constraints.each(function(constraint) {
+                  if (constraint.get('columns').length == 0) {
+                    removed.push(constraint);
+                  }
+                });
+                constraints.remove(removed);
+              },100);
+
+            },
+            resetColOptions : function(m) {
+              var self = this,
+                updatedCols = self.model.get('columns').where(
+                  {column: m.previous('name')}
+                );
+              if (updatedCols.length > 0) {
+                /*
+                 * Table column name has changed so update
+                 * column name in primary key as well.
+                 */
+                updatedCols[0].set(
+                  {'column': m.get('name')},
+                  {silent: true});
+              }
+
+              setTimeout(function () {
+                self.render();
+              }, 10);
+            },
+            formatter: {
+              fromRaw: function (rawValue) {
+                return rawValue.pluck('column').toString();
+              },
+              toRaw: function (val) { return val; },
+            },
+            render: function() {
+              return Backgrid.StringCell.prototype.render.apply(this, arguments);
+            },
+            remove: function() {
+              var tableCols = this.model.top.get('columns'),
+                primary_key_col = this.model.get('columns');
+
+              if (primary_key_col) {
+                primary_key_col.off('pgadmin:multicolumn:updated');
+              }
+
+              this.stopListening(tableCols, 'remove' , self.removeColumn);
+              this.stopListening(tableCols, 'change:name' , self.resetColOptions);
+
+              Backgrid.StringCell.prototype.remove.apply(this, arguments);
+            },
+          }),
+          canDelete: true, canAdd: true,
+          control: Backform.MultiSelectAjaxControl.extend({
+            defaults: _.extend(
+              {},
+              Backform.NodeListByNameControl.prototype.defaults,
+              {
+                select2: {
+                  multiple: true,
+                  allowClear: true,
+                  width: 'style',
+                  placeholder: gettext('Select the column(s)'),
+                },
+              }
+            ),
+            keyPathAccessor: function(obj, path) {
+              var res = obj;
+              if(_.isArray(res)) {
+                return _.map(res, function(o) { return o['column'];
+                });
+              }
+              path = path.split('.');
+              for (var i = 0; i < path.length; i++) {
+                if (_.isNull(res)) return null;
+                if (_.isEmpty(path[i])) continue;
+                if (!_.isUndefined(res[path[i]])) res = res[path[i]];
+              }
+              return _.isObject(res) && !_.isArray(res) ? null : res;
+            },
+            initialize: function() {
+              // Here we will decide if we need to call URL
+              // Or fetch the data from parent columns collection
+              var self = this;
+              if(this.model.handler) {
+                Backform.Select2Control.prototype.initialize.apply(this, arguments);
+                // Do not listen for any event(s) for existing constraint.
+                if (_.isUndefined(self.model.get('oid'))) {
+                  var tableCols = self.model.top.get('columns');
+                  self.listenTo(tableCols, 'remove' , self.resetColOptions);
+                  self.listenTo(tableCols, 'change:name', self.resetColOptions);
+                }
+
+                self.custom_options();
+              } else {
+                Backform.MultiSelectAjaxControl.prototype.initialize.apply(this, arguments);
+              }
+              self.model.get('columns').on('pgadmin:multicolumn:updated', function() {
+                self.render.apply(self);
+              });
+            },
+            resetColOptions: function() {
+              var self = this;
+
+              setTimeout(function () {
+                self.custom_options();
+                self.render.apply(self);
+              }, 50);
+            },
+            custom_options: function() {
+              // We will add all the columns entered by user in table model
+              var columns = this.model.top.get('columns'),
+                added_columns_from_tables = [];
+
+              if (columns.length > 0) {
+                _.each(columns.models, function(m) {
+                  var col = m.get('name');
+                  if(!_.isUndefined(col) && !_.isNull(col)) {
+                    added_columns_from_tables.push(
+                      {label: col, value: col, image:'icon-column'}
+                    );
+                  }
+                });
+              }
+              // Set the values in to options so that user can select
+              this.field.set('options', added_columns_from_tables);
+            },
+            onChange: function() {
+              var self = this,
+                model = this.model,
+                attrArr = this.field.get('name').split('.'),
+                name = attrArr.shift(),
+                vals = this.getValueFromDOM(),
+                collection = model.get(name),
+                removed = [];
+
+              this.stopListening(this.model, 'change:' + name, this.render);
+
+              /*
+                 * Iterate through all the values, and find out how many are already
+                 * present in the collection.
+                 */
+              collection.each(function(m) {
+                var column = m.get('column'),
+                  idx = _.indexOf(vals, column);
+
+                if (idx > -1) {
+                  vals.splice(idx, 1);
+                } else {
+                  removed.push(column);
+                }
+              });
+
+              /*
+                 * Adding new values
+                 */
+
+              _.each(vals, function(v) {
+                var m = new (self.field.get('model'))(
+                  {column: v}, { silent: true,
+                    top: self.model.top,
+                    collection: collection,
+                    handler: collection,
+                  });
+
+                collection.add(m);
+              });
+
+              /*
+                 * Removing unwanted!
+                 */
+              _.each(removed, function(v) {
+                collection.remove(collection.where({column: v}));
+              });
+
+              this.listenTo(this.model, 'change:' + name, this.render);
+            },
+            remove: function() {
+              if(this.model.handler) {
+                var self = this,
+                  tableCols = self.model.top.get('columns');
+                self.stopListening(tableCols, 'remove' , self.resetColOptions);
+                self.stopListening(tableCols, 'change:name' , self.resetColOptions);
+                self.model.get('columns').off('pgadmin:multicolumn:updated');
+
+                Backform.Select2Control.prototype.remove.apply(this, arguments);
+
+              } else {
+                Backform.MultiSelectAjaxControl.prototype.remove.apply(this, arguments);
+              }
+            },
+            render: function() {
+              var index = this.model.get('index');
+              if(!_.isUndefined(index) && index != '') {
+                var col = this.model.get('columns');
+                col.reset([], {silent: true});
+              }
+              return Backform.Select2Control.prototype.render.apply(this, arguments);
+            },
+          }),
+          deps: ['index'], node: 'column',
+          model: pgBrowser.Node.Model.extend({
+            defaults: {
+              column: undefined,
+            },
+            validate: function() {
+              return null;
+            },
+          }),
+          transform : function(data){
+            var res = [];
+            if (data && _.isArray(data)) {
+              _.each(data, function(d) {
+                res.push({label: d.label, value: d.label, image:'icon-column'});
+              });
+            }
+            return res;
+          },
+          select2:{allowClear:false},
+          readonly: function(m) {
+            // If we are in table edit mode then
+            if (_.has(m, 'top') && !_.isUndefined(m.top)
+              && !m.top.isNew()) {
+              // If OID is undefined then user is trying to add
+              // new constraint which should be allowed for Unique
+              return !_.isUndefined(m.get('oid'));
+            }
+
+            // We can't update columns of existing index constraint.
+            if (!m.isNew()) {
+              return true;
+            }
+          },
+          disabled: function(m) {
+            // Disable if index is selected.
+            var index = m.get('index');
+            return !(_.isUndefined(index) || index == '');
+          },
+        },{
+          id: 'include', label: gettext('Include columns'),
+          type: 'array', group: gettext('Definition'),
+          editable: false,
+          canDelete: true, canAdd: true, mode: ['properties', 'create', 'edit'],
+          visible: function(m) {
+            /* In table properties, m.node_info is not available */
+            m = m.top;
+            if(!_.isUndefined(m.node_info) && !_.isUndefined(m.node_info.server)
+              && !_.isUndefined(m.node_info.server.version) &&
+              m.node_info.server.version >= 110000)
+              return true;
+
+            return false;
+          },
+          control: Backform.MultiSelectAjaxControl.extend({
+            defaults: _.extend(
+              {},
+              Backform.NodeListByNameControl.prototype.defaults,
+              {
+                select2: {
+                  allowClear: false,
+                  width: 'style',
+                  multiple: true,
+                  placeholder: gettext('Select the column(s)'),
+                },
+              }
+            ),
+            initialize: function() {
+              // Here we will decide if we need to call URL
+              // Or fetch the data from parent columns collection
+              var self = this;
+              if(this.model.handler) {
+                Backform.Select2Control.prototype.initialize.apply(this, arguments);
+                // Do not listen for any event(s) for existing constraint.
+                if (_.isUndefined(self.model.get('oid'))) {
+                  var tableCols = self.model.top.get('columns');
+                  self.listenTo(tableCols, 'remove' , self.resetColOptions);
+                  self.listenTo(tableCols, 'change:name', self.resetColOptions);
+                }
+
+                self.custom_options();
+              } else {
+                Backform.MultiSelectAjaxControl.prototype.initialize.apply(this, arguments);
+              }
+            },
+            resetColOptions: function() {
+              var self = this;
+
+              setTimeout(function () {
+                self.custom_options();
+                self.render.apply(self);
+              }, 50);
+            },
+            custom_options: function() {
+              // We will add all the columns entered by user in table model
+              var columns = this.model.top.get('columns'),
+                added_columns_from_tables = [];
+
+              if (columns.length > 0) {
+                _.each(columns.models, function(m) {
+                  var col = m.get('name');
+                  if(!_.isUndefined(col) && !_.isNull(col)) {
+                    added_columns_from_tables.push(
+                      {label: col, value: col, image:'icon-column'}
+                    );
+                  }
+                });
+              }
+              // Set the values in to options so that user can select
+              this.field.set('options', added_columns_from_tables);
+            },
+          }),
+          deps: ['index'], node: 'column',
+          readonly: function(m) {
+            // If we are in table edit mode then
+            if (_.has(m, 'top') && !_.isUndefined(m.top)
+              && !m.top.isNew()) {
+              // If OID is undefined then user is trying to add
+              // new constraint which should be allowed for Unique
+              return !_.isUndefined(m.get('oid'));
+            }
+
+            // We can't update columns of existing index constraint.
+            if (!m.isNew()) {
+              return true;
+            }
+          },
+          disabled: function(m) {
+            // Disable if index is selected.
+            var index = m.get('index');
+            if(_.isUndefined(index) || index == '') {
+              return false;
+            } else {
+              setTimeout(function(){
+                m.set('include', []);
+              },10);
+              return true;
+            }
+          },
+        },{
+          id: 'spcname', label: gettext('Tablespace'),
+          type: 'text', group: gettext('Definition'),
+          control: 'node-list-by-name', node: 'tablespace',
+          deps: ['index'],
+          select2:{allowClear:false},
+          filter: function(m) {
+            // Don't show pg_global tablespace in selection.
+            return (m.label != 'pg_global');
+          },
+          disabled: function(m) {
+            // Disable if index is selected.
+            m = m.top || m;
+            var index = m.get('index');
+            if(_.isUndefined(index) || index == '') {
+              return false;
+            } else {
+              setTimeout(function(){
+                m.set('spcname', '');
+              },10);
+              return true;
+            }
+          },
+        },{
+          id: 'index', label: gettext('Index'),
+          mode: ['create'],
+          type: 'text', group: gettext('Definition'),
+          control: Backform.NodeListByNameControl.extend({
+            initialize:function() {
+              Backform.NodeListByNameControl.prototype.initialize.apply(this, arguments);
+            },
+          }),
+          select2:{allowClear:true}, node: 'index',
+          readonly: function(m) {
+            // If we are in table edit mode then disable it
+            if (_.has(m, 'top') && !_.isUndefined(m.top)
+              && !m.top.isNew()) {
+              return true;
+            }
+
+            // We can't update index of existing index constraint.
+            return !m.isNew();
+          },
+          // We will not show this field in Create Table mode
+          visible: function(m) {
+            return !_.isUndefined(m.top.node_info['table']);
+          },
+        },{
+          id: 'fillfactor', label: gettext('Fill factor'), deps: ['index'],
+          type: 'int', group: gettext('Definition'), allowNull: true,
+          disabled: function(m) {
+            // Disable if index is selected.
+            var index = m.get('index');
+            if(_.isUndefined(index) || index == '') {
+              return false;
+            } else {
+              setTimeout(function(){
+                m.set('fillfactor', null);
+              },10);
+              return true;
+            }
+          },
+        },{
+          id: 'condeferrable', label: gettext('Deferrable?'),
+          type: 'switch', group: gettext('Definition'), deps: ['index'],
+          readonly: function(m) {
+            // If we are in table edit mode then
+            if (_.has(m, 'top') && !_.isUndefined(m.top)
+              && !m.top.isNew()) {
+              // If OID is undefined then user is trying to add
+              // new constraint which should allowed for Unique
+              return !_.isUndefined(m.get('oid'));
+            }
+
+            // We can't update condeferrable of existing index constraint.
+            if (!m.isNew()) {
+              return true;
+            }
+          },
+          disabled: function(m) {
+            // Disable if index is selected.
+            var index = m.get('index');
+            if(_.isUndefined(index) || index == '') {
+              return false;
+            } else {
+              setTimeout(function(){
+                if(m.get('condeferrable'))
+                  m.set('condeferrable', false);
+              },10);
+              return true;
+            }
+          },
+        },{
+          id: 'condeferred', label: gettext('Deferred?'),
+          type: 'switch', group: gettext('Definition'),
+          deps: ['condeferrable'],
+          readonly: function(m) {
+            // If we are in table edit mode then
+            if (_.has(m, 'top') && !_.isUndefined(m.top)
+              && !m.top.isNew()) {
+              // If OID is undefined then user is trying to add
+              // new constraint which should allowed for Unique
+              return !_.isUndefined(m.get('oid'));
+            }
+
+            // We can't update condeferred of existing index constraint.
+            if (!m.isNew()) {
+              return true;
+            }
+          },
+          disabled: function(m) {
+            // Disable if condeferred is false or unselected.
+            if(m.get('condeferrable') == true) {
+              return false;
+            } else {
+              setTimeout(function(){
+                if(m.get('condeferred'))
+                  m.set('condeferred', false);
+              },10);
+              return true;
+            }
+          },
+        },
+        ],
+        validate: function() {
+          this.errorModel.clear();
+          // Clear parent's error as well
+          if (_.has(this, 'top')) {
+            this.top.errorModel.clear();
+          }
+
+          var columns = this.get('columns'),
+            index = this.get('index');
+
+          if ((_.isUndefined(index) || String(index).replace(/^\s+|\s+$/g, '') == '') &&
+            (_.isUndefined(columns) || _.isNull(columns) || columns.length < 1)) {
+            var msg = gettext('Please specify columns for %s.', gettext('Primary key'));
+            this.errorModel.set('columns', msg);
+            return msg;
+          }
+
+          return null;
+        },
+      }),
     });
   }
 
