diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
index 3d41fd3..9eb25c7 100644
--- a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
+++ b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTable.java
@@ -14,6 +14,7 @@
 import java.util.List;
 
 import javax.swing.AbstractAction;
+import javax.swing.DropMode;
 import javax.swing.JComponent;
 import javax.swing.JPopupMenu;
 import javax.swing.JTable;
@@ -82,6 +83,11 @@ protected void init() {
         //
         getActionMap().put("selectNextColumnCell", new SelectNextColumnCellAction());
         getActionMap().put("selectPreviousColumnCell", new SelectPreviousColumnCellAction());
+
+        setTransferHandler(new MemberTransferHandler());
+        setFillsViewportHeight(true); // allow drop on empty table
+        setDragEnabled(true);
+        setDropMode(DropMode.INSERT_ROWS);
     }
 
     @Override
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
index f87ef71..6047f94 100644
--- a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
+++ b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
@@ -446,6 +446,14 @@ private void addMembersAtIndex(List<? extends OsmPrimitive> primitives, int inde
         fireMakeMemberVisible(index);
     }
 
+    void addMembersAtIndex(final Iterable<RelationMember> newMembers, final int index) {
+        int idx = index;
+        for (RelationMember member : newMembers) {
+            members.add(idx++, member);
+        }
+        fireTableRowsInserted(index, idx - 1);
+    }
+
     public void addMembersAtBeginning(List<? extends OsmPrimitive> primitives) {
         addMembersAtIndex(primitives, 0);
     }
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java
new file mode 100644
index 0000000..d544be2
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java
@@ -0,0 +1,85 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.dialogs.relation;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import javax.swing.TransferHandler;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.RelationMemberData;
+
+class MemberTransferHandler extends TransferHandler {
+
+    @Override
+    public int getSourceActions(JComponent c) {
+        return COPY_OR_MOVE;
+    }
+
+    @Override
+    protected Transferable createTransferable(JComponent c) {
+        final MemberTable source = (MemberTable) c;
+        return new MemberTransferable(source.getMemberTableModel().getSelectedMembers());
+    }
+
+    @Override
+    public boolean canImport(TransferSupport support) {
+        support.setShowDropLocation(true);
+        return support.isDataFlavorSupported(MemberTransferable.RELATION_MEMBER_DATA);
+    }
+
+    @Override
+    public boolean importData(TransferSupport support) {
+        final int insertRow = ((JTable.DropLocation) support.getDropLocation()).getRow();
+        final Collection<RelationMemberData> memberData;
+        try {
+            //noinspection unchecked
+            memberData = (Collection<RelationMemberData>) support.getTransferable().getTransferData(MemberTransferable.RELATION_MEMBER_DATA);
+        } catch (UnsupportedFlavorException | IOException e) {
+            Main.warn(e);
+            return false;
+        }
+        final MemberTable destination = (MemberTable) support.getComponent();
+
+        try {
+            importRelationMemberData(memberData, destination, insertRow);
+        } catch (Exception e) {
+            Main.warn(e);
+            throw e;
+        }
+        return true;
+    }
+
+    protected void importRelationMemberData(Collection<RelationMemberData> memberData, MemberTable destination, int insertRow) {
+        final Collection<RelationMember> membersToAdd = new ArrayList<>(memberData.size());
+        for (RelationMemberData member : memberData) {
+            final OsmPrimitive p = destination.getLayer().data.getPrimitiveById(member.getUniqueId(), member.getType());
+            if (p != null) {
+                membersToAdd.add(new RelationMember(member.getRole(), p));
+            } else {
+                Main.warn(tr("Cannot add {0} since it is not part of dataset", member));
+            }
+        }
+        destination.getMemberTableModel().addMembersAtIndex(membersToAdd, insertRow);
+    }
+
+    @Override
+    protected void exportDone(JComponent sourceComponent, Transferable data, int action) {
+        if (action != MOVE) {
+            return;
+        }
+        final MemberTable source = (MemberTable) sourceComponent;
+        final MemberTableModel model = source.getMemberTableModel();
+        model.remove(source.getSelectedRows());
+        model.selectionChanged(null);
+    }
+}
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferable.java b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferable.java
new file mode 100644
index 0000000..b3d2d53
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferable.java
@@ -0,0 +1,62 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.dialogs.relation;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.RelationMemberData;
+import org.openstreetmap.josm.gui.DefaultNameFormatter;
+
+class MemberTransferable implements Transferable {
+
+    static final DataFlavor RELATION_MEMBER_DATA = new DataFlavor(RelationMemberData.class, "MemberTransferable");
+    private final Collection<RelationMember> members;
+
+    public MemberTransferable(Collection<RelationMember> members) {
+        this.members = members;
+    }
+
+    @Override
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[]{RELATION_MEMBER_DATA, DataFlavor.stringFlavor};
+    }
+
+    @Override
+    public boolean isDataFlavorSupported(DataFlavor flavor) {
+        return flavor == RELATION_MEMBER_DATA;
+    }
+
+    @Override
+    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
+        if (DataFlavor.stringFlavor.equals(flavor)) {
+            return getStringData();
+        } else if (RELATION_MEMBER_DATA.equals(flavor)) {
+            return getRelationMemberData();
+        }
+        throw new UnsupportedFlavorException(flavor);
+    }
+
+    protected String getStringData() {
+        final StringBuilder sb = new StringBuilder();
+        for (RelationMember member : members) {
+            sb.append(member.getType());
+            sb.append(" ").append(member.getUniqueId());
+            sb.append(" ").append(member.getRole());
+            sb.append(" #").append(member.getMember().getDisplayName(DefaultNameFormatter.getInstance()));
+            sb.append("\n");
+        }
+        return sb.toString().replace("\u200E", "").replace("\u200F", "");
+    }
+
+    protected Collection<RelationMemberData> getRelationMemberData() {
+        final Collection<RelationMemberData> r = new ArrayList<>(members.size());
+        for (RelationMember member : members) {
+            r.add(new RelationMemberData(member.getRole(), member.getType(), member.getUniqueId()));
+        }
+        return r;
+    }
+}
