diff --git a/patches/gromacs-5.1.2.diff/src/programs/mdrun/md.cpp b/patches/gromacs-5.1.2.diff/src/programs/mdrun/md.cpp
index 0007817df2c5c9c4f44428e8742ba03a31627d66..4c552329584542397e34e6645e136882d4925374 100644
--- a/patches/gromacs-5.1.2.diff/src/programs/mdrun/md.cpp
+++ b/patches/gromacs-5.1.2.diff/src/programs/mdrun/md.cpp
@@ -122,6 +122,10 @@ extern int    plumedswitch;
 extern plumed plumedmain;
 /* END PLUMED */
 
+/* PLUMED HREX */
+extern int plumed_hrex;
+/* END PLUMED HREX */
+
 #ifdef GMX_FAHCORE
 #include "corewrap.h"
 #endif
@@ -1043,6 +1047,83 @@ double do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[],
         }
         clear_mat(force_vir);
 
+/* PLUMED HREX */
+        gmx_bool bHREX;
+        bHREX= repl_ex_nst > 0 && (step>0) && !bLastStep && do_per_step(step,repl_ex_nst) && plumed_hrex;
+
+        if(plumedswitch) if(bHREX){
+          gmx_enerdata_t *hrex_enerd;
+          snew(hrex_enerd,1);
+          init_enerdata(top_global->groups.grps[egcENER].nr,ir->fepvals->n_lambda,hrex_enerd);
+          int repl=-1;
+          int nrepl=-1;
+          if(MASTER(cr)){
+            repl=replica_exchange_get_repl(repl_ex);
+            nrepl=replica_exchange_get_nrepl(repl_ex);
+          }
+          if (PAR(cr)) {
+            if (DOMAINDECOMP(cr))
+              dd_collect_state(cr->dd,state,state_global);
+          }
+          if(MASTER(cr)){
+            if(repl%2==step/repl_ex_nst%2){
+              if(repl-1>=0) exchange_state(cr->ms,repl-1,state_global);
+            }else{
+              if(repl+1<nrepl) exchange_state(cr->ms,repl+1,state_global);
+            }
+          }
+          if(PAR(cr)){
+            if (DOMAINDECOMP(cr)) {
+              dd_partition_system(fplog,step,cr,TRUE,1,
+                              state_global,top_global,ir,
+                              state,&f,mdatoms,top,fr,vsite,shellfc,constr,
+                              nrnb,wcycle,FALSE);
+            }
+          }
+          do_force(fplog, cr, ir, step, nrnb, wcycle, top, groups,
+                     state->box, state->x, &state->hist,
+                     f, force_vir, mdatoms, hrex_enerd, fcd,
+                     state->lambda, graph,
+                     fr, vsite, mu_tot, t, mdoutf_get_fp_field(outf), ed, bBornRadii,
+                    GMX_FORCE_STATECHANGED |
+                       ((DYNAMIC_BOX(*ir) || bRerunMD) ? GMX_FORCE_DYNAMICBOX : 0) |
+                       GMX_FORCE_ALLFORCES |
+                       GMX_FORCE_SEPLRF |
+                       GMX_FORCE_VIRIAL |
+                       GMX_FORCE_ENERGY |
+                       GMX_FORCE_DHDL |
+                       GMX_FORCE_NS);
+          plumed_cmd(plumedmain,"GREX cacheLocalUSwap",&hrex_enerd->term[F_EPOT]);
+          sfree(hrex_enerd);
+
+/* exchange back */
+          if (PAR(cr)) {
+            if (DOMAINDECOMP(cr))
+              dd_collect_state(cr->dd,state,state_global);
+          }
+          if(MASTER(cr)){
+            if(repl%2==step/repl_ex_nst%2){
+              if(repl-1>=0) exchange_state(cr->ms,repl-1,state_global);
+            }else{
+              if(repl+1<nrepl) exchange_state(cr->ms,repl+1,state_global);
+            }
+          }
+          if(PAR(cr)){
+            if (DOMAINDECOMP(cr)) {
+              dd_partition_system(fplog,step,cr,TRUE,1,
+                              state_global,top_global,ir,
+                              state,&f,mdatoms,top,fr,vsite,shellfc,constr,
+                              nrnb,wcycle,FALSE);
+              if(plumedswitch){
+                plumed_cmd(plumedmain,"setAtomsNlocal",&cr->dd->nat_home);
+                plumed_cmd(plumedmain,"setAtomsGatindex",cr->dd->gatindex);
+              }
+            }
+          }
+
+        }
+/* END PLUMED HREX */
+
         /* We write a checkpoint at this MD step when:
          * either at an NS step when we signalled through gs,
          * or at the last step (but not when we do not want confout),
@@ -1176,6 +1257,8 @@ double do_md(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[],
               if ((repl_ex_nst > 0) && (step > 0) && !bLastStep &&
                  do_per_step(step,repl_ex_nst)) plumed_cmd(plumedmain,"GREX savePositions",NULL);
               if(plumedWantsToStop) ir->nsteps=step_rel+1;
+              if(bHREX)
+                 plumed_cmd(plumedmain,"GREX cacheLocalUNow",&enerd->term[F_EPOT]);
             }
             /* END PLUMED */
         }
diff --git a/patches/gromacs-5.1.2.diff/src/programs/mdrun/mdrun.cpp b/patches/gromacs-5.1.2.diff/src/programs/mdrun/mdrun.cpp
index 626a3c002f342e3a948d0fd55b2dd8fd7d521ceb..e249f8d9ae7ea0b6ebc46bc96e2411a30c718784 100644
--- a/patches/gromacs-5.1.2.diff/src/programs/mdrun/mdrun.cpp
+++ b/patches/gromacs-5.1.2.diff/src/programs/mdrun/mdrun.cpp
@@ -78,6 +78,10 @@ extern plumed plumedmain;
 extern void(*plumedcmd)(plumed,const char*,const void*);
 /* END PLUMED */
 
+/* PLUMED HREX */
+int plumed_hrex;
+/* END PLUMED HREX */
+
 /*! \brief Return whether either of the command-line parameters that
  *  will trigger a multi-simulation is set */
 static bool is_multisim_option_set(int argc, const char *const argv[])
@@ -406,6 +410,8 @@ int gmx_mdrun(int argc, char *argv[])
           "Number of random exchanges to carry out each exchange interval (N^3 is one suggestion).  -nex zero or not specified gives neighbor replica exchange." },
         { "-reseed",  FALSE, etINT, {&repl_ex_seed},
           "Seed for replica exchange, -1 is generate a seed" },
+        { "-hrex",  FALSE, etBOOL, {&plumed_hrex},
+          "Enable hamiltonian replica exchange" },
         { "-imdport",    FALSE, etINT, {&imdport},
           "HIDDENIMD listening port" },
         { "-imdwait",  FALSE, etBOOL, {&bIMDwait},
@@ -565,6 +571,15 @@ int gmx_mdrun(int argc, char *argv[])
       plumed_cmd(plumedmain,"setPlumedDat",ftp2fn(efDAT,NFILE,fnm));
       plumedswitch=1;
     }
+    /* PLUMED HREX*/
+    if(getenv("PLUMED_HREX")) plumed_hrex=1;
+    if(plumed_hrex){
+      if(!plumedswitch)  gmx_fatal(FARGS,"-hrex (or PLUMED_HREX) requires -plumed");
+      if(repl_ex_nst==0) gmx_fatal(FARGS,"-hrex (or PLUMED_HREX) replica exchange");
+      if(repl_ex_nex!=0) gmx_fatal(FARGS,"-hrex (or PLUMED_HREX) not compatible with -nex");
+    }
+    /* END PLUMED HREX */
+
     /* END PLUMED */
 
     rc = mdrunner(&hw_opt, fplog, cr, NFILE, fnm, oenv, bVerbose, bCompact,
diff --git a/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.cpp b/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.cpp
index c4683cf8328329416493885da79c0bb86885168d..b42f551376e58d39e1fec537c7336abe4b62b192 100644
--- a/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.cpp
+++ b/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.cpp
@@ -59,6 +59,10 @@ extern int    plumedswitch;
 extern plumed plumedmain;
 /* END PLUMED */
 
+/* PLUMED HREX */
+extern int plumed_hrex;
+/* END PLUMED HREX */
+
 #define PROBABILITYCUTOFF 100
 /* we don't bother evaluating if events are more rare than exp(-100) = 3.7x10^-44 */
 
@@ -566,7 +570,7 @@ static void exchange_rvecs(const gmx_multisim_t gmx_unused *ms, int gmx_unused b
     }
 }
 
-static void exchange_state(const gmx_multisim_t *ms, int b, t_state *state)
+void exchange_state(const gmx_multisim_t *ms, int b, t_state *state)
 {
     /* When t_state changes, this code should be updated. */
     int ngtc, nnhpres;
@@ -1002,6 +1006,8 @@ test_for_replica_exchange(FILE                 *fplog,
     int plumed_test_exchange_pattern=0;
     /* END PLUMED */
 
+    if(plumed_test_exchange_pattern && plumed_hrex) gmx_fatal(FARGS,"hrex not compatible with ad hoc exchange patterns");
+
     if (bMultiEx)
     {
         /* multiple random switch exchange */
@@ -1111,6 +1117,10 @@ test_for_replica_exchange(FILE                 *fplog,
             if (i % 2 == m)
             {
                 delta = calc_delta(fplog, bPrint, re, a, b, a, b);
+/* this is necessary because with plumed HREX the energy contribution is
+   already taken into account */
+                if(plumed_hrex) delta=0.0;
+
                 /* PLUMED */
                 if(plumedswitch){
                   real adb,bdb,dplumed;
@@ -1518,3 +1528,13 @@ void print_replica_exchange_statistics(FILE *fplog, struct gmx_repl_ex *re)
     /* print the transition matrix */
     print_transition_matrix(fplog, re->nrepl, re->nmoves, re->nattempt);
 }
+
+
+int replica_exchange_get_repl(const gmx_repl_ex_t re){
+  return re->repl;
+};
+
+int replica_exchange_get_nrepl(const gmx_repl_ex_t re){
+  return re->nrepl;
+};
+
diff --git a/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.h b/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa51f07b440ed436ebc85454d15d0d4b459f8d28
--- /dev/null
+++ b/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.h
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+
+#ifndef _repl_ex_h
+#define _repl_ex_h
+
+#include "gromacs/legacyheaders/typedefs.h"
+#include "gromacs/legacyheaders/types/commrec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Abstract type for replica exchange */
+typedef struct gmx_repl_ex *gmx_repl_ex_t;
+
+extern gmx_repl_ex_t init_replica_exchange(FILE *fplog,
+                                           const gmx_multisim_t *ms,
+                                           const t_state *state,
+                                           const t_inputrec *ir,
+                                           int nst, int nmultiex, int init_seed);
+/* Should only be called on the master nodes */
+
+extern gmx_bool replica_exchange(FILE *fplog,
+                                 const t_commrec *cr,
+                                 gmx_repl_ex_t re,
+                                 t_state *state, gmx_enerdata_t *enerd,
+                                 t_state *state_local,
+                                 gmx_int64_t step, real time);
+/* Attempts replica exchange, should be called on all nodes.
+ * Returns TRUE if this state has been exchanged.
+ * When running each replica in parallel,
+ * this routine collects the state on the master node before exchange.
+ * With domain decomposition, the global state after exchange is stored
+ * in state and still needs to be redistributed over the nodes.
+ */
+
+extern void print_replica_exchange_statistics(FILE *fplog, gmx_repl_ex_t re);
+/* Should only be called on the master nodes */
+
+extern int replica_exchange_get_repl(const gmx_repl_ex_t re);
+extern int replica_exchange_get_nrepl(const gmx_repl_ex_t re);
+extern void pd_collect_state(const t_commrec *cr, t_state *state);
+extern void exchange_state(const gmx_multisim_t *ms, int b, t_state *state);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _repl_ex_h */
diff --git a/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.h.preplumed b/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.h.preplumed
new file mode 100644
index 0000000000000000000000000000000000000000..ffedd2305f626acdec1086a2aaa0169a029548f8
--- /dev/null
+++ b/patches/gromacs-5.1.2.diff/src/programs/mdrun/repl_ex.h.preplumed
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+
+#ifndef _repl_ex_h
+#define _repl_ex_h
+
+#include "gromacs/legacyheaders/typedefs.h"
+#include "gromacs/legacyheaders/types/commrec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Abstract type for replica exchange */
+typedef struct gmx_repl_ex *gmx_repl_ex_t;
+
+extern gmx_repl_ex_t init_replica_exchange(FILE *fplog,
+                                           const gmx_multisim_t *ms,
+                                           const t_state *state,
+                                           const t_inputrec *ir,
+                                           int nst, int nmultiex, int init_seed);
+/* Should only be called on the master nodes */
+
+extern gmx_bool replica_exchange(FILE *fplog,
+                                 const t_commrec *cr,
+                                 gmx_repl_ex_t re,
+                                 t_state *state, gmx_enerdata_t *enerd,
+                                 t_state *state_local,
+                                 gmx_int64_t step, real time);
+/* Attempts replica exchange, should be called on all nodes.
+ * Returns TRUE if this state has been exchanged.
+ * When running each replica in parallel,
+ * this routine collects the state on the master node before exchange.
+ * With domain decomposition, the global state after exchange is stored
+ * in state and still needs to be redistributed over the nodes.
+ */
+
+extern void print_replica_exchange_statistics(FILE *fplog, gmx_repl_ex_t re);
+/* Should only be called on the master nodes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _repl_ex_h */