diff --git a/docs/en_US/erd_tool.rst b/docs/en_US/erd_tool.rst
index e8493fc9a..e828b9978 100644
--- a/docs/en_US/erd_tool.rst
+++ b/docs/en_US/erd_tool.rst
@@ -12,6 +12,7 @@ The Entity-Relationship Diagram (ERD) tool is a database design tool that provid
 * Save the diagram and open it later to continue working on it.
 * Generate ready to run SQL from the database design.
 * Generate the database diagram for an existing database.
+* Drag and drop tables from browser tree to the diagram.
 
 .. image:: images/erd_tool.png
     :alt: ERD tool window
diff --git a/docs/en_US/images/erd_1m_dialog.png b/docs/en_US/images/erd_1m_dialog.png
index 3c341b16a68b355568f8f6b4f912d72be0b85b67..df6629a7bede455122f7fe455706e301c7323ae3 100644
GIT binary patch
diff --git a/docs/en_US/images/erd_mm_dialog.png b/docs/en_US/images/erd_mm_dialog.png
index 3465d1f1433208923c46198c631656aba8ebf48d..25621bde7ab654258195970972decc3d0f99e895 100644
GIT binary patch
diff --git a/docs/en_US/images/erd_table_dialog.png b/docs/en_US/images/erd_table_dialog.png
index 3b6b1f263dafd11653df81efd1c386b763a27f75..8eec7f07c4e4d5fdb2682cf689c8c195b2ab80d0 100644
GIT binary patch
diff --git a/web/pgadmin/browser/static/js/browser.js b/web/pgadmin/browser/static/js/browser.js
index 108dc4d86..f88fb6584 100644
--- a/web/pgadmin/browser/static/js/browser.js
+++ b/web/pgadmin/browser/static/js/browser.js
@@ -7,6 +7,8 @@
 //
 //////////////////////////////////////////////////////////////
 
+import { generateNodeUrl } from './node_ajax';
+
 define('pgadmin.browser', [
   'sources/gettext', 'sources/url_for', 'require', 'jquery', 'underscore',
   'bootstrap', 'sources/pgadmin', 'pgadmin.alertifyjs', 'bundled_codemirror',
@@ -61,8 +63,16 @@ define('pgadmin.browser', [
     function(b) {
       InitTree.initBrowserTree(b).then(() => {
         b.tree.registerDraggableType({
-          'collation domain domain_constraints fts_configuration fts_dictionary fts_parser fts_template synonym table partition type sequence package view mview foreign_table edbvar' : (data, item)=>{
-            return pgadminUtils.fully_qualify(b, data, item);
+          'collation domain domain_constraints fts_configuration fts_dictionary fts_parser fts_template synonym table partition type sequence package view mview foreign_table edbvar' : (data, item, treeNodeInfo)=>{
+            let text = pgadminUtils.fully_qualify(b, data, item);
+            return {
+              text: text,
+              objUrl: generateNodeUrl.call(pgBrowser.Nodes[data._type], treeNodeInfo, 'properties', data, true),
+              cur: {
+                from: text.length,
+                to: text.length,
+              },
+            };
           },
           'schema column database cast event_trigger extension language foreign_data_wrapper foreign_server user_mapping compound_trigger index index_constraint primary_key unique_constraint check_constraint exclusion_constraint foreign_key rule' : (data)=>{
             return pgadminUtils.quote_ident(data._label);
diff --git a/web/pgadmin/static/js/tree/tree.js b/web/pgadmin/static/js/tree/tree.js
index 41835b3bf..2bc31e737 100644
--- a/web/pgadmin/static/js/tree/tree.js
+++ b/web/pgadmin/static/js/tree/tree.js
@@ -459,7 +459,7 @@ export class Tree {
        * overrides the dragstart event set using element.on('dragstart')
        * This will avoid conflict.
        */
-      let dropDetails = dropDetailsFunc(data, item);
+      let dropDetails = dropDetailsFunc(data, item, this.getTreeNodeHierarchy(item));
 
       if(typeof dropDetails == 'string') {
         dropDetails = {
diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js b/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js
index 60dbf4e34..44ffca5e0 100644
--- a/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js
+++ b/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js
@@ -175,11 +175,12 @@ export default class ERDCore {
 
   getModel() {return this.getEngine().getModel();}
 
-  getNewNode(initData) {
+  getNewNode(initData, dataUrl=null) {
     return this.getEngine().getNodeFactories().getFactory('table').generateModel({
       initialConfig: {
         otherInfo: {
           data:initData,
+          dataUrl: dataUrl,
         },
       },
     });
@@ -404,6 +405,21 @@ export default class ERDCore {
     this.repaint();
   }
 
+  cloneTableData(tableData, name) {
+    const SKIP_CLONE_KEYS = ['foreign_key'];
+
+    if(!tableData) {
+      return tableData;
+    }
+    let newData = {
+      ..._.pickBy(tableData, (_v, k)=>(SKIP_CLONE_KEYS.indexOf(k) == -1)),
+    };
+    if(name) {
+      newData['name'] = name;
+    }
+    return newData;
+  }
+
   serialize(version) {
     return {
       version: version||0,
@@ -422,7 +438,10 @@ export default class ERDCore {
     let nodesDict = this.getModel().getNodesDict();
 
     Object.keys(nodesDict).forEach((id)=>{
-      nodes[id] = nodesDict[id].serializeData();
+      let nodeData = nodesDict[id].serializeData();
+      if(nodeData) {
+        nodes[id] = nodeData;
+      }
     });
 
     return {
diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/nodes/TableNode.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/nodes/TableNode.jsx
index fb43fa768..945047810 100644
--- a/web/pgadmin/tools/erd/static/js/erd_tool/nodes/TableNode.jsx
+++ b/web/pgadmin/tools/erd/static/js/erd_tool/nodes/TableNode.jsx
@@ -18,6 +18,7 @@ import PrimaryKeyIcon from 'top/browser/server_groups/servers/databases/schemas/
 import ForeignKeyIcon from 'top/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/img/foreign_key.svg';
 import ColumnIcon from 'top/browser/server_groups/servers/databases/schemas/tables/columns/static/img/column.svg';
 import PropTypes from 'prop-types';
+import gettext from 'sources/gettext';
 
 const TYPE = 'table';
 
@@ -29,11 +30,34 @@ export class TableNodeModel extends DefaultNodeModel {
     });
 
     this._note = otherInfo.note || '';
-
-    this._data = {
-      columns: [],
-      ...otherInfo.data,
+    this._metadata = {
+      data_failed: false,
+      ...otherInfo.metadata,
+      is_promise: Boolean(otherInfo.data?.then || (otherInfo.metadata?.data_failed && !otherInfo.data)),
     };
+    this._data = null;
+    if(otherInfo.data?.then) {
+      otherInfo.data.then((data)=>{
+        /* Once the data is available, it is no more a promise */
+        this._data = data;
+        this._metadata = {
+          data_failed: false,
+          is_promise: false,
+        };
+        this.fireEvent(this._metadata, 'dataAvaiable');
+      }).catch(()=>{
+        this._metadata = {
+          data_failed: true,
+          is_promise: true,
+        };
+        this.fireEvent(this._metadata, 'dataAvaiable');
+      });
+    } else {
+      this._data = {
+        columns: [],
+        ...otherInfo.data,
+      };
+    }
   }
 
   getPortName(attnum) {
@@ -48,6 +72,10 @@ export class TableNodeModel extends DefaultNodeModel {
     return this._note;
   }
 
+  getMetadata() {
+    return this._metadata;
+  }
+
   addColumn(col) {
     this._data.columns.push(col);
   }
@@ -64,17 +92,6 @@ export class TableNodeModel extends DefaultNodeModel {
     this._data['name'] = name;
   }
 
-  cloneData(name) {
-    const SKIP_CLONE_KEYS = ['foreign_key'];
-    let newData = {
-      ..._.pickBy(this.getData(), (_v, k)=>(SKIP_CLONE_KEYS.indexOf(k) == -1)),
-    };
-    if(name) {
-      newData['name'] = name;
-    }
-    return newData;
-  }
-
   setData(data) {
     let self = this;
     /* Remove the links if column dropped or primary key removed */
@@ -116,6 +133,7 @@ export class TableNodeModel extends DefaultNodeModel {
       otherInfo: {
         data: this.getData(),
         note: this.getNote(),
+        metadata: this.getMetadata(),
       },
     };
   }
@@ -146,6 +164,10 @@ export class TableNodeWidget extends React.Component {
       toggleDetails: (event) => {
         this.setState({show_details: event.show_details});
       },
+      dataAvaiable: ()=>{
+        /* Just re-render */
+        this.setState({});
+      }
     });
   }
 
@@ -192,26 +214,37 @@ export class TableNodeWidget extends React.Component {
 
   render() {
     let tableData = this.props.node.getData();
+    let tableMetaData = this.props.node.getMetadata();
     return (
       <div className={'table-node ' + (this.props.node.isSelected() ? 'selected': '') } onDoubleClick={()=>{this.props.node.fireEvent({}, 'editTable');}}>
         <div className="table-toolbar">
-          <DetailsToggleButton className='btn-xs' showDetails={this.state.show_details} onClick={this.toggleShowDetails} onDoubleClick={(e)=>{e.stopPropagation();}} />
+          <DetailsToggleButton className='btn-xs' showDetails={this.state.show_details}
+            onClick={this.toggleShowDetails} onDoubleClick={(e)=>{e.stopPropagation();}}
+            disabled={tableMetaData.is_promise} />
           {this.props.node.getNote() &&
             <IconButton icon="far fa-sticky-note" className="btn-xs btn-warning ml-auto" onClick={()=>{
               this.props.node.fireEvent({}, 'showNote');
-            }} title="Check note" />}
-        </div>
-        <div className="d-flex table-schema-data">
-          <RowIcon icon={SchemaIcon}/>
-          <div className="table-schema my-auto">{tableData.schema}</div>
-        </div>
-        <div className="d-flex table-name-data">
-          <RowIcon icon={TableIcon} />
-          <div className="table-name my-auto">{tableData.name}</div>
-        </div>
-        <div className="table-cols">
-          {_.map(tableData.columns, (col)=>this.generateColumn(col, tableData))}
+            }} title="Check note"/>}
         </div>
+        {tableMetaData.is_promise && <>
+          <div className="d-flex table-name-data">
+            {!tableMetaData.data_failed && <div className="table-name my-auto">{gettext('Fetching...')}</div>}
+            {tableMetaData.data_failed && <div className="table-name my-auto fetch-error">{gettext('Failed to get data. Please delete this table.')}</div>}
+          </div>
+        </>}
+        {!tableMetaData.is_promise && <>
+          <div className="d-flex table-schema-data">
+            <RowIcon icon={SchemaIcon}/>
+            <div className="table-schema my-auto">{tableData.schema}</div>
+          </div>
+          <div className="d-flex table-name-data">
+            <RowIcon icon={TableIcon} />
+            <div className="table-name my-auto">{tableData.name}</div>
+          </div>
+          <div className="table-cols">
+            {_.map(tableData.columns, (col)=>this.generateColumn(col, tableData))}
+          </div>
+        </>}
       </div>
     );
   }
diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
index 4ff8825c1..ffd25e127 100644
--- a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
+++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
@@ -26,6 +26,7 @@ import url_for from 'sources/url_for';
 import {showERDSqlTool} from 'tools/datagrid/static/js/show_query_tool';
 import 'wcdocker';
 import Theme from '../../../../../../static/js/Theme';
+import TableSchema from '../../../../../../browser/server_groups/servers/databases/schemas/tables/static/js/table.ui';
 
 /* Custom react-diagram action for keyboard events */
 export class KeyboardShortcutAction extends Action {
@@ -94,7 +95,7 @@ export default class BodyWidget extends React.Component {
     _.bindAll(this, ['onLoadDiagram', 'onSaveDiagram', 'onSaveAsDiagram', 'onSQLClick',
       'onImageClick', 'onAddNewNode', 'onEditTable', 'onCloneNode', 'onDeleteNode', 'onNoteClick',
       'onNoteClose', 'onOneToManyClick', 'onManyToManyClick', 'onAutoDistribute', 'onDetailsToggle',
-      'onDetailsToggle', 'onHelpClick'
+      'onDetailsToggle', 'onHelpClick', 'onDropNode',
     ]);
 
     this.diagram.zoomToFit = this.diagram.zoomToFit.bind(this.diagram);
@@ -361,6 +362,29 @@ export default class BodyWidget extends React.Component {
     }
   }
 
+  onDropNode(e) {
+    let nodeDropData = JSON.parse(e.dataTransfer.getData('text'));
+    if(nodeDropData.objUrl) {
+      let matchUrl = `/${this.props.params.sgid}/${this.props.params.sid}/${this.props.params.did}/`;
+      if(nodeDropData.objUrl.indexOf(matchUrl) == -1) {
+        this.props.alertify.error(gettext('Cannot drop table from outside of the current database.'));
+      } else {
+        let dataPromise = new Promise((resolve, reject)=>{
+          axios.get(nodeDropData.objUrl)
+            .then((res)=>{
+              resolve(this.diagram.cloneTableData(TableSchema.getErdSupportedData(res.data)));
+            })
+            .catch((err)=>{
+              console.error(err);
+              reject();
+            });
+        });
+        const {x, y} = this.diagram.getEngine().getRelativeMousePoint(e);
+        this.diagram.addNode(dataPromise, [x, y]).setSelected(true);
+      }
+    }
+  }
+
   onEditTable() {
     const selected = this.diagram.getSelectedNodes();
     if(selected.length == 1) {
@@ -375,10 +399,12 @@ export default class BodyWidget extends React.Component {
   onCloneNode() {
     const selected = this.diagram.getSelectedNodes();
     if(selected.length == 1) {
-      let newData = selected[0].cloneData(this.diagram.getNextTableName());
-      let {x, y} = selected[0].getPosition();
-      let newNode = this.diagram.addNode(newData, [x+20, y+20]);
-      newNode.setSelected(true);
+      let newData = this.diagram.cloneTableData(selected[0].getData(), this.diagram.getNextTableName());
+      if(newData) {
+        let {x, y} = selected[0].getPosition();
+        let newNode = this.diagram.addNode(newData, [x+20, y+20]);
+        newNode.setSelected(true);
+      }
     }
   }
 
@@ -825,7 +851,7 @@ export default class BodyWidget extends React.Component {
           fgcolor={this.props.params.fgcolor} title={this.props.params.title}/>
         <FloatingNote open={this.state.note_open} onClose={this.onNoteClose}
           reference={this.noteRefEle} noteNode={this.state.note_node} appendTo={this.diagramContainerRef.current} rows={8}/>
-        <div className="diagram-container" ref={this.diagramContainerRef}>
+        <div className="diagram-container" ref={this.diagramContainerRef} onDrop={this.onDropNode} onDragOver={e => {e.preventDefault();}}>
           <Loader message={this.state.loading_msg} autoEllipsis={true}/>
           <CanvasWidget className="diagram-canvas flex-grow-1" ref={(ele)=>{this.canvasEle = ele?.ref?.current;}} engine={this.diagram.getEngine()} />
         </div>
diff --git a/web/pgadmin/tools/erd/static/scss/_erd.scss b/web/pgadmin/tools/erd/static/scss/_erd.scss
index 150ef6778..6b6ccdf9d 100644
--- a/web/pgadmin/tools/erd/static/scss/_erd.scss
+++ b/web/pgadmin/tools/erd/static/scss/_erd.scss
@@ -135,6 +135,10 @@
           font-weight: bold;
           word-break: break-all;
         }
+
+        & .fetch-error {
+          color: $color-danger;
+        }
       }
 
       .table-cols {
diff --git a/web/regression/javascript/erd/erd_core_spec.js b/web/regression/javascript/erd/erd_core_spec.js
index 635d488d4..1f84dee46 100644
--- a/web/regression/javascript/erd/erd_core_spec.js
+++ b/web/regression/javascript/erd/erd_core_spec.js
@@ -101,6 +101,7 @@ describe('ERDCore', ()=>{
         initialConfig: {
           otherInfo: {
             data:data,
+            dataUrl: null,
           },
         },
       });
diff --git a/web/regression/javascript/erd/table_node_spec.js b/web/regression/javascript/erd/table_node_spec.js
index 37d45e99b..43e45efb7 100644
--- a/web/regression/javascript/erd/table_node_spec.js
+++ b/web/regression/javascript/erd/table_node_spec.js
@@ -63,15 +63,6 @@ describe('ERD TableNodeModel', ()=>{
     expect(modelObj.getData().name).toBe('changedName');
   });
 
-  it('cloneData', ()=>{
-    modelObj.addColumn({name: 'col1', not_null:false, attnum: 0});
-    expect(modelObj.cloneData('clonedNode')).toEqual({
-      name: 'clonedNode',
-      schema: 'erd',
-      columns: [{name: 'col1', not_null:false, attnum: 0}],
-    });
-  });
-
   describe('setData', ()=>{
     let existPort = jasmine.createSpyObj('port', {
       'removeAllLinks': jasmine.createSpy('removeAllLinks'),
@@ -196,6 +187,9 @@ describe('ERD TableNodeModel', ()=>{
           schema: 'erd',
         },
         note: 'some note',
+        metadata: {
+          data_failed: false, is_promise: false
+        }
       },
     });
   });
