diff --git a/easyblocks/i/impi.py b/easyblocks/i/impi.py
new file mode 100644
index 0000000000000000000000000000000000000000..c0d16508f883ec304bb398465a9f75cfb71d5668
--- /dev/null
+++ b/easyblocks/i/impi.py
@@ -0,0 +1,290 @@
+# #
+# Copyright 2009-2020 Ghent University
+#
+# This file is part of EasyBuild,
+# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
+# with support of Ghent University (http://ugent.be/hpc),
+# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
+# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
+# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
+#
+# https://github.com/easybuilders/easybuild
+#
+# EasyBuild is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation v2.
+#
+# EasyBuild 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
+# #
+"""
+EasyBuild support for installing the Intel MPI library, implemented as an easyblock
+
+@author: Stijn De Weirdt (Ghent University)
+@author: Dries Verdegem (Ghent University)
+@author: Kenneth Hoste (Ghent University)
+@author: Pieter De Baets (Ghent University)
+@author: Jens Timmerman (Ghent University)
+@author: Damian Alvarez (Forschungszentrum Juelich GmbH)
+"""
+import os
+from distutils.version import LooseVersion
+
+from easybuild.easyblocks.generic.intelbase import IntelBase, ACTIVATION_NAME_2012, LICENSE_FILE_NAME_2012
+from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.filetools import apply_regex_substitutions, change_dir, extract_file, mkdir, write_file
+from easybuild.tools.run import run_cmd
+from easybuild.tools.systemtools import get_shared_lib_ext
+
+
+class EB_impi(IntelBase):
+    """
+    Support for installing Intel MPI library
+    """
+    @staticmethod
+    def extra_options():
+        extra_vars = {
+            'libfabric_configopts': ['', 'Configure options for the provided libfabric', CUSTOM],
+            'libfabric_rebuild': [True, 'Try to rebuild internal libfabric instead of using provided binary', CUSTOM],
+            'ofi_internal': [True, 'Use internal shipped libfabric instead of external libfabric', CUSTOM],
+            'set_mpi_wrappers_compiler': [False, 'Override default compiler used by MPI wrapper commands', CUSTOM],
+            'set_mpi_wrapper_aliases_gcc': [False, 'Set compiler for mpigcc/mpigxx via aliases', CUSTOM],
+            'set_mpi_wrapper_aliases_intel': [False, 'Set compiler for mpiicc/mpiicpc/mpiifort via aliases', CUSTOM],
+            'set_mpi_wrappers_all': [False, 'Set (default) compiler for all MPI wrapper commands', CUSTOM],
+        }
+        return IntelBase.extra_options(extra_vars)
+
+    def prepare_step(self, *args, **kwargs):
+        if LooseVersion(self.version) >= LooseVersion('2017.2.174'):
+            kwargs['requires_runtime_license'] = False
+            super(EB_impi, self).prepare_step(*args, **kwargs)
+        else:
+            super(EB_impi, self).prepare_step(*args, **kwargs)
+
+    def install_step(self):
+        """
+        Actual installation
+        - create silent cfg file
+        - execute command
+        """
+        impiver = LooseVersion(self.version)
+        if impiver >= LooseVersion('4.0.1'):
+            # impi starting from version 4.0.1.x uses standard installation procedure.
+
+            silent_cfg_names_map = {}
+
+            if impiver < LooseVersion('4.1.1'):
+                # since impi v4.1.1, silent.cfg has been slightly changed to be 'more standard'
+                silent_cfg_names_map.update({
+                    'activation_name': ACTIVATION_NAME_2012,
+                    'license_file_name': LICENSE_FILE_NAME_2012,
+                })
+
+            super(EB_impi, self).install_step(silent_cfg_names_map=silent_cfg_names_map)
+
+            # impi v4.1.1 and v5.0.1 installers create impi/<version> subdir, so stuff needs to be moved afterwards
+            if impiver == LooseVersion('4.1.1.036') or impiver >= LooseVersion('5.0.1.035'):
+                super(EB_impi, self).move_after_install()
+        else:
+            # impi up until version 4.0.0.x uses custom installation procedure.
+            silent = """[mpi]
+INSTALLDIR=%(ins)s
+LICENSEPATH=%(lic)s
+INSTALLMODE=NONRPM
+INSTALLUSER=NONROOT
+UPDATE_LD_SO_CONF=NO
+PROCEED_WITHOUT_PYTHON=yes
+AUTOMOUNTED_CLUSTER=yes
+EULA=accept
+[mpi-rt]
+INSTALLDIR=%(ins)s
+LICENSEPATH=%(lic)s
+INSTALLMODE=NONRPM
+INSTALLUSER=NONROOT
+UPDATE_LD_SO_CONF=NO
+PROCEED_WITHOUT_PYTHON=yes
+AUTOMOUNTED_CLUSTER=yes
+EULA=accept
+
+""" % {'lic': self.license_file, 'ins': self.installdir}
+
+            # already in correct directory
+            silentcfg = os.path.join(os.getcwd(), "silent.cfg")
+            write_file(silentcfg, silent)
+            self.log.debug("Contents of %s: %s", silentcfg, silent)
+
+            tmpdir = os.path.join(os.getcwd(), self.version, 'mytmpdir')
+            mkdir(tmpdir, parents=True)
+
+            cmd = "./install.sh --tmp-dir=%s --silent=%s" % (tmpdir, silentcfg)
+            run_cmd(cmd, log_all=True, simple=True)
+
+        # recompile libfabric (if requested)
+        # some Intel MPI versions (like 2019 update 6) no longer ship libfabric sources
+        libfabric_path = os.path.join(self.installdir, 'libfabric')
+        if impiver >= LooseVersion('2019') and self.cfg['libfabric_rebuild']:
+            if self.cfg['ofi_internal']:
+                libfabric_src_tgz_fn = 'src.tgz'
+                if os.path.exists(os.path.join(libfabric_path, libfabric_src_tgz_fn)):
+                    change_dir(libfabric_path)
+                    extract_file(libfabric_src_tgz_fn, os.getcwd())
+                    libfabric_installpath = os.path.join(self.installdir, 'intel64', 'libfabric')
+
+                    make = 'make'
+                    if self.cfg['parallel']:
+                        make += ' -j %d' % self.cfg['parallel']
+
+                    cmds = [
+                        './configure --prefix=%s %s' % (libfabric_installpath, self.cfg['libfabric_configopts']),
+                        make,
+                        'make install'
+                    ]
+                    for cmd in cmds:
+                        run_cmd(cmd, log_all=True, simple=True)
+                else:
+                    self.log.info("Rebuild of libfabric is requested, but %s does not exist, so skipping...",
+                                  libfabric_src_tgz_fn)
+            else:
+                raise EasyBuildError("Rebuild of libfabric is requested, but ofi_internal is set to False.")
+
+    def post_install_step(self):
+        """Custom post install step for IMPI, fix broken env scripts after moving installed files."""
+        super(EB_impi, self).post_install_step()
+
+        impiver = LooseVersion(self.version)
+        if impiver == LooseVersion('4.1.1.036') or impiver >= LooseVersion('5.0.1.035'):
+            if impiver >= LooseVersion('2018.0.128'):
+                script_paths = [os.path.join('intel64', 'bin')]
+            else:
+                script_paths = [os.path.join('intel64', 'bin'), os.path.join('mic', 'bin')]
+            # fix broken env scripts after the move
+            regex_subs = [(r"^setenv I_MPI_ROOT.*", r"setenv I_MPI_ROOT %s" % self.installdir)]
+            for script in [os.path.join(script_path, 'mpivars.csh') for script_path in script_paths]:
+                apply_regex_substitutions(os.path.join(self.installdir, script), regex_subs)
+            regex_subs = [(r"^I_MPI_ROOT=.*", r"I_MPI_ROOT=%s; export I_MPI_ROOT" % self.installdir)]
+            for script in [os.path.join(script_path, 'mpivars.sh') for script_path in script_paths]:
+                apply_regex_substitutions(os.path.join(self.installdir, script), regex_subs)
+
+            # fix 'prefix=' in compiler wrapper scripts after moving installation (see install_step)
+            wrappers = ['mpif77', 'mpif90', 'mpigcc', 'mpigxx', 'mpiicc', 'mpiicpc', 'mpiifort']
+            regex_subs = [(r"^prefix=.*", r"prefix=%s" % self.installdir)]
+            for script_dir in script_paths:
+                for wrapper in wrappers:
+                    wrapper_path = os.path.join(self.installdir, script_dir, wrapper)
+                    if os.path.exists(wrapper_path):
+                        apply_regex_substitutions(wrapper_path, regex_subs)
+
+    def sanity_check_step(self):
+        """Custom sanity check paths for IMPI."""
+
+        suff = "64"
+        if self.cfg['m32']:
+            suff = ""
+
+        mpi_mods = ['mpi.mod']
+        if LooseVersion(self.version) > LooseVersion('4.0'):
+            mpi_mods.extend(["mpi_base.mod", "mpi_constants.mod", "mpi_sizeofs.mod"])
+
+        if LooseVersion(self.version) >= LooseVersion('2019'):
+            bin_dir = 'intel64/bin'
+            include_dir = 'intel64/include'
+            lib_dir = 'intel64/lib/release'
+        else:
+            bin_dir = 'bin%s' % suff
+            include_dir = 'include%s' % suff
+            lib_dir = 'lib%s' % suff
+            mpi_mods.extend(["i_malloc.h"])
+
+        custom_paths = {
+            'files': ["%s/mpi%s" % (bin_dir, x) for x in ["icc", "icpc", "ifort"]] +
+                    ["%s/mpi%s.h" % (include_dir, x) for x in ["cxx", "f", "", "o", "of"]] +
+                    ["%s/%s" % (include_dir, x) for x in mpi_mods] +
+                    ["%s/libmpi.%s" % (lib_dir, get_shared_lib_ext())] +
+                    ["%s/libmpi.a" % lib_dir],
+            'dirs': [],
+        }
+
+        super(EB_impi, self).sanity_check_step(custom_paths=custom_paths)
+
+    def make_module_req_guess(self):
+        """
+        A dictionary of possible directories to look for
+        """
+        if self.cfg['m32']:
+            lib_dirs = ['lib', 'lib/ia32', 'ia32/lib']
+            include_dirs = ['include']
+            return {
+                'PATH': ['bin', 'bin/ia32', 'ia32/bin'],
+                'LD_LIBRARY_PATH': lib_dirs,
+                'LIBRARY_PATH': lib_dirs,
+                'MANPATH': ['man'],
+                'CPATH': include_dirs,
+                'MIC_LD_LIBRARY_PATH': ['mic/lib'],
+            }
+        else:
+            guesses = {}
+            if LooseVersion(self.version) >= LooseVersion('2019'):
+                # Keep release_mt and release in front, to give priority to the possible symlinks in intel64/lib.
+                # IntelMPI 2019 changed the default library to be the non-mt version.
+                lib_dirs = ['intel64/%s' % x for x in ['lib/release_mt', 'lib/release', 'lib']]
+                include_dirs = ['intel64/include']
+                path_dirs = ['intel64/bin']
+                if self.cfg['ofi_internal']:
+                    lib_dirs.append('intel64/libfabric/lib')
+                    path_dirs.append('intel64/libfabric/bin')
+                    guesses['FI_PROVIDER_PATH'] = ['intel64/libfabric/lib/prov']
+            else:
+                lib_dirs = ['lib/em64t', 'lib64']
+                include_dirs = ['include64']
+                path_dirs = ['bin/intel64', 'bin64']
+                guesses['MIC_LD_LIBRARY_PATH'] = ['mic/lib']
+
+            guesses.update({
+                'PATH': path_dirs,
+                'LD_LIBRARY_PATH': lib_dirs,
+                'LIBRARY_PATH': lib_dirs,
+                'MANPATH': ['man'],
+                'CPATH': include_dirs,
+            })
+
+            return guesses
+
+    def make_module_extra(self, *args, **kwargs):
+        """Overwritten from Application to add extra txt"""
+        txt = super(EB_impi, self).make_module_extra(*args, **kwargs)
+        txt += self.module_generator.set_environment('I_MPI_ROOT', self.installdir)
+        if self.cfg['set_mpi_wrappers_compiler'] or self.cfg['set_mpi_wrappers_all']:
+            for var in ['CC', 'CXX', 'F77', 'F90', 'FC']:
+                if var == 'FC':
+                    # $FC isn't defined by EasyBuild framework, so use $F90 instead
+                    src_var = 'F90'
+                else:
+                    src_var = var
+
+                target_var = 'I_MPI_%s' % var
+
+                val = os.getenv(src_var)
+                if val:
+                    txt += self.module_generator.set_environment(target_var, val)
+                else:
+                    raise EasyBuildError("Environment variable $%s not set, can't define $%s", src_var, target_var)
+
+        if self.cfg['set_mpi_wrapper_aliases_gcc'] or self.cfg['set_mpi_wrappers_all']:
+            # force mpigcc/mpigxx to use GCC compilers, as would be expected based on their name
+            txt += self.module_generator.set_alias('mpigcc', 'mpigcc -cc=gcc')
+            txt += self.module_generator.set_alias('mpigxx', 'mpigxx -cxx=g++')
+
+        if self.cfg['set_mpi_wrapper_aliases_intel'] or self.cfg['set_mpi_wrappers_all']:
+            # do the same for mpiicc/mpiipc/mpiifort to be consistent, even if they may not exist
+            txt += self.module_generator.set_alias('mpiicc', 'mpiicc -cc=icc')
+            txt += self.module_generator.set_alias('mpiicpc', 'mpiicpc -cxx=icpc')
+            # -fc also works, but -f90 takes precedence
+            txt += self.module_generator.set_alias('mpiifort', 'mpiifort -f90=ifort')
+
+        return txt