diff --git a/lib/spack/spack/compilers/gcc.py b/lib/spack/spack/compilers/gcc.py
index a556f346d73cb8080a9fe77024e23eae57c6305e..9ea314efd58789409f84e7b1dfc9c435db498c01 100644
--- a/lib/spack/spack/compilers/gcc.py
+++ b/lib/spack/spack/compilers/gcc.py
@@ -83,3 +83,7 @@ def fc_version(cls, fc):
     @classmethod
     def f77_version(cls, f77):
         return cls.fc_version(f77)
+
+    @property
+    def stdcxx_libs(self):
+        return ('-lstdc++', )
diff --git a/lib/spack/spack/compilers/intel.py b/lib/spack/spack/compilers/intel.py
index 4f0c12140f827da7052d10432526e1e14fd79e83..14f4d2dc91d4830b71bd9ab85bb7913ded1f707c 100644
--- a/lib/spack/spack/compilers/intel.py
+++ b/lib/spack/spack/compilers/intel.py
@@ -80,3 +80,7 @@ def default_version(cls, comp):
         """
         return get_compiler_version(
             comp, '--version', r'\((?:IFORT|ICC)\) ([^ ]+)')
+
+    @property
+    def stdcxx_libs(self):
+        return ('-cxxlib', )
diff --git a/var/spack/repos/builtin/packages/cp2k/package.py b/var/spack/repos/builtin/packages/cp2k/package.py
index ce9675d30078e274a68e0b24184a3e21f40164fd..052c7a971cb1710b675bc70dc25a76c92bdecfea 100644
--- a/var/spack/repos/builtin/packages/cp2k/package.py
+++ b/var/spack/repos/builtin/packages/cp2k/package.py
@@ -52,12 +52,12 @@ class Cp2k(Package):
     depends_on('scalapack', when='+mpi')
     depends_on('plumed+shared+mpi', when='+plumed+mpi')
     depends_on('plumed+shared~mpi', when='+plumed~mpi')
+    depends_on('pexsi', when='+mpi')
 
     # TODO : add dependency on libint
     # TODO : add dependency on libsmm, libxsmm
     # TODO : add dependency on elpa
     # TODO : add dependency on CUDA
-    # TODO : add dependency on PEXSI
     # TODO : add dependency on QUIP
     # TODO : add dependency on libwannier90
 
@@ -88,6 +88,7 @@ def install(self, spec, prefix):
             }
             cppflags = [
                 '-D__FFTW3',
+                '-D__LIBPEXSI',
                 '-I' + spec['fftw'].prefix.include
             ]
             fcflags = copy.deepcopy(optflags[self.spec.compiler.name])
@@ -144,11 +145,28 @@ def install(self, spec, prefix):
                     '-D__parallel',
                     '-D__SCALAPACK'
                 ])
+                fcflags.extend([
+                    '-I' + join_path(spec['pexsi'].prefix, 'fortran')
+                ])
                 ldflags.extend([
                     '-L' + spec['scalapack'].prefix.lib
                 ])
+                libs.extend([
+                    join_path(spec['pexsi'].prefix.lib, 'libpexsi.a'),
+                    join_path(spec['superlu-dist'].prefix.lib,
+                              'libsuperlu_dist.a'),
+                    join_path(
+                        spec['parmetis'].prefix.lib,
+                        'libparmetis.{0}'.format(dso_suffix)
+                    ),
+                    join_path(
+                        spec['metis'].prefix.lib,
+                        'libmetis.{0}'.format(dso_suffix)
+                    ),
+                ])
                 libs.extend(spec['scalapack'].scalapack_shared_libs)
-
+                libs.extend(self.spec['mpi'].mpicxx_shared_libs)
+                libs.extend(self.compiler.stdcxx_libs)
             # LAPACK / BLAS
             ldflags.extend([
                 '-L' + spec['lapack'].prefix.lib,
diff --git a/var/spack/repos/builtin/packages/mpich/package.py b/var/spack/repos/builtin/packages/mpich/package.py
index 90670ee517e69b06efd3bea107a12cf456d7b7fe..a36ab4206e73b92c6b24c0bd78748f9d8c69d099 100644
--- a/var/spack/repos/builtin/packages/mpich/package.py
+++ b/var/spack/repos/builtin/packages/mpich/package.py
@@ -66,6 +66,10 @@ def setup_dependent_package(self, module, dep_spec):
         self.spec.mpicxx = join_path(self.prefix.bin, 'mpic++')
         self.spec.mpifc = join_path(self.prefix.bin, 'mpif90')
         self.spec.mpif77 = join_path(self.prefix.bin, 'mpif77')
+        self.spec.mpicxx_shared_libs = [
+            join_path(self.prefix.lib, 'libmpicxx.{0}'.format(dso_suffix)),
+            join_path(self.prefix.lib, 'libmpi.{0}'.format(dso_suffix))
+        ]
 
     def install(self, spec, prefix):
         config_args = ["--prefix=" + prefix,
diff --git a/var/spack/repos/builtin/packages/mvapich2/package.py b/var/spack/repos/builtin/packages/mvapich2/package.py
index 54caf0e7e185c334938e7c929b41264716e18bcf..a123830185e670245fcb1d01eaab5e1544db5cc3 100644
--- a/var/spack/repos/builtin/packages/mvapich2/package.py
+++ b/var/spack/repos/builtin/packages/mvapich2/package.py
@@ -227,6 +227,10 @@ def setup_dependent_package(self, module, dep_spec):
         self.spec.mpicxx = join_path(self.prefix.bin, 'mpicxx')
         self.spec.mpifc  = join_path(self.prefix.bin, 'mpif90')
         self.spec.mpif77 = join_path(self.prefix.bin, 'mpif77')
+        self.spec.mpicxx_shared_libs = [
+            join_path(self.prefix.lib, 'libmpicxx.{0}'.format(dso_suffix)),
+            join_path(self.prefix.lib, 'libmpi.{0}'.format(dso_suffix))
+        ]
 
     def install(self, spec, prefix):
         # we'll set different configure flags depending on our
diff --git a/var/spack/repos/builtin/packages/openmpi/package.py b/var/spack/repos/builtin/packages/openmpi/package.py
index f13feb123df98b3b9e04ed1de686d65b9f3bb1cf..ca6bd473f1ec258736ad744104be221a337ace19 100644
--- a/var/spack/repos/builtin/packages/openmpi/package.py
+++ b/var/spack/repos/builtin/packages/openmpi/package.py
@@ -129,6 +129,10 @@ def setup_dependent_package(self, module, dep_spec):
         self.spec.mpicxx = join_path(self.prefix.bin, 'mpic++')
         self.spec.mpifc = join_path(self.prefix.bin, 'mpif90')
         self.spec.mpif77 = join_path(self.prefix.bin, 'mpif77')
+        self.spec.mpicxx_shared_libs = [
+            join_path(self.prefix.lib, 'libmpi_cxx.{0}'.format(dso_suffix)),
+            join_path(self.prefix.lib, 'libmpi.{0}'.format(dso_suffix))
+        ]
 
     def setup_environment(self, spack_env, run_env):
         # As of 06/2016 there is no mechanism to specify that packages which
diff --git a/var/spack/repos/builtin/packages/pexsi/make.inc b/var/spack/repos/builtin/packages/pexsi/make.inc
new file mode 100644
index 0000000000000000000000000000000000000000..a8020fb370be3157ea750f4e4852014fc373c620
--- /dev/null
+++ b/var/spack/repos/builtin/packages/pexsi/make.inc
@@ -0,0 +1,79 @@
+# Different compiling and linking options.
+SUFFIX = linux
+
+# Compiler and tools
+################################################################
+CC = @MPICC
+CXX = @MPICXX
+FC = @MPIFC
+LOADER = @MPICXX
+
+
+AR = ar
+ARFLAGS = rvcu
+# For System V based machine without ranlib, like Cray and SGI,
+# use touch instead.
+RANLIB = @RANLIB
+
+CP = cp
+RM = rm
+RMFLAGS = -f
+################################################################
+
+# PEXSI directory
+PEXSI_DIR = @PEXSI_STAGE
+
+# Required libraries directories
+DSUPERLU_DIR = @SUPERLU_PREFIX
+METIS_DIR = @METIS_PREFIX
+PARMETIS_DIR = @PARMETIS_PREFIX
+LAPACK_DIR = @LAPACK_PREFIX
+BLAS_DIR = @BLAS_PREFIX
+
+# Includes
+PEXSI_INCLUDE = -I${PEXSI_DIR}/include
+DSUPERLU_INCLUDE = -I${DSUPERLU_DIR}/include
+INCLUDES = ${PEXSI_INCLUDE} ${DSUPERLU_INCLUDE}
+
+# Libraries
+CPP_LIB = @STDCXX_LIB @MPICXX_LIB
+#GFORTRAN_LIB = /usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortran.a
+LAPACK_LIB = @LAPACK_LIBS
+BLAS_LIB = @BLAS_LIBS
+DSUPERLU_LIB = ${DSUPERLU_DIR}/lib/libsuperlu_dist.a
+PEXSI_LIB = ${PEXSI_DIR}/src/libpexsi_${SUFFIX}.a
+
+# Graph partitioning libraries
+METIS_LIB = -L${METIS_DIR}/lib -lmetis
+PARMETIS_LIB = -L${PARMETIS_DIR}/libparmetis -lparmetis
+
+# Different compiling and linking options.
+COMPILE_DEF = -DDEBUG=0 -DRELEASE
+COMPILE_FLAG = -O3 -w
+
+LIBS  = ${PEXSI_LIB} ${DSUPERLU_LIB} ${PARMETIS_LIB} ${METIS_LIB} ${LAPACK_LIB} ${BLAS_LIB} ${GFORTRAN_LIB}
+
+COMPILE_DEF  += -DAdd_
+
+CPPFLAG = -std=c++11
+
+CFLAGS       = ${COMPILE_FLAG} ${PROFILE_FLAG} ${INCLUDES}
+FFLAGS       = ${COMPILE_FLAG} ${PROFILE_FLAG} ${INCLUDES}
+CXXFLAGS     = ${COMPILE_FLAG} ${CPPFLAG} ${PROFILE_FLAG} ${INCLUDES}
+CCDEFS       = ${COMPILE_DEF}
+CPPDEFS      = ${COMPILE_DEF}
+LOADOPTS     = ${PROFILE_FLAG} ${LIBS}
+FLOADOPTS    = ${PROFILE_FLAG} ${LIBS} ${CPP_LIB}
+
+# Generate auto-dependencies
+%.d: %.c
+	@set -e; rm -f $@; \
+	$(CC) -M $(CCDEFS) $(CFLAGS) $< > $@.$$$$; \
+	sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;\
+	rm -f $@.$$$$
+
+%.d: %.cpp
+	@set -e; rm -f $@; \
+	$(CXX) -M $(CPPDEFS) $(CXXFLAGS) $< > $@.$$$$; \
+	sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;\
+	rm -f $@.$$$$
diff --git a/var/spack/repos/builtin/packages/pexsi/package.py b/var/spack/repos/builtin/packages/pexsi/package.py
new file mode 100644
index 0000000000000000000000000000000000000000..e74ad6df013ec44b99c75b3e1b628af3f1003cda
--- /dev/null
+++ b/var/spack/repos/builtin/packages/pexsi/package.py
@@ -0,0 +1,103 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program 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) version 2.1, February 1999.
+#
+# This program 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 terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+
+import inspect
+import os.path
+import shutil
+
+from spack import *
+
+
+class Pexsi(Package):
+    """The PEXSI library is written in C++, and uses message passing interface
+    (MPI) to parallelize the computation on distributed memory computing
+    systems and achieve scalability on more than 10,000 processors.
+
+    The Pole EXpansion and Selected Inversion (PEXSI) method is a fast
+    method for electronic structure calculation based on Kohn-Sham density
+    functional theory. It efficiently evaluates certain selected elements
+    of matrix functions, e.g., the Fermi-Dirac function of the KS Hamiltonian,
+    which yields a density matrix. It can be used as an alternative to
+    diagonalization methods for obtaining the density, energy and forces
+    in electronic structure calculations.
+    """
+    homepage = 'https://math.berkeley.edu/~linlin/pexsi/index.html'
+    url = 'https://math.berkeley.edu/~linlin/pexsi/download/pexsi_v0.9.0.tar.gz'
+
+    version('0.9.0', '0c1a2de891ba1445dfc184b2fa270ed8')
+
+    depends_on('parmetis')
+    depends_on('superlu-dist@3.3', when='@0.9.0')
+
+    parallel = False
+
+    def install(self, spec, prefix):
+
+        substitutions = {
+            '@MPICC': self.spec['mpi'].mpicc,
+            '@MPICXX': self.spec['mpi'].mpicxx,
+            '@MPIFC': self.spec['mpi'].mpifc,
+            '@MPICXX_LIB': ' '.join(self.spec['mpi'].mpicxx_shared_libs),
+            '@RANLIB': 'ranlib',
+            '@PEXSI_STAGE': self.stage.source_path,
+            '@SUPERLU_PREFIX': self.spec['superlu-dist'].prefix,
+            '@METIS_PREFIX': self.spec['metis'].prefix,
+            '@PARMETIS_PREFIX': self.spec['parmetis'].prefix,
+            '@LAPACK_PREFIX': self.spec['lapack'].prefix,
+            '@BLAS_PREFIX': self.spec['blas'].prefix,
+            '@LAPACK_LIBS': self.spec['lapack'].lapack_shared_lib,
+            '@BLAS_LIBS': self.spec['lapack'].blas_shared_lib,
+            '@STDCXX_LIB': ' '.join(self.compiler.stdcxx_libs)
+        }
+
+        template = join_path(
+            os.path.dirname(inspect.getmodule(self).__file__),
+            'make.inc'
+        )
+        makefile = join_path(
+            self.stage.source_path,
+            'make.inc'
+        )
+        shutil.copy(template, makefile)
+        for key, value in substitutions.items():
+            filter_file(key, value, makefile)
+
+        make()
+        # 'make install' does not exist, despite what documentation says
+        mkdirp(self.prefix.lib)
+        install(
+            join_path(self.stage.source_path, 'src', 'libpexsi_linux.a'),
+            join_path(self.prefix.lib, 'libpexsi.a')
+        )
+        install_tree(
+            join_path(self.stage.source_path, 'include'),
+            self.prefix.include
+        )
+        # fortran "interface"
+        make('-C', 'fortran')
+        install_tree(
+            join_path(self.stage.source_path, 'fortran'),
+            join_path(self.prefix, 'fortran')
+        )
diff --git a/var/spack/repos/builtin/packages/superlu-dist/package.py b/var/spack/repos/builtin/packages/superlu-dist/package.py
index 4b3354e379d3478b601d5c686c87ab782728dcad..85b7f689d0f805e43e708adc9f0c55e6aa1b9f3a 100644
--- a/var/spack/repos/builtin/packages/superlu-dist/package.py
+++ b/var/spack/repos/builtin/packages/superlu-dist/package.py
@@ -30,13 +30,14 @@ class SuperluDist(Package):
     """A general purpose library for the direct solution of large, sparse,
     nonsymmetric systems of linear equations on high performance machines."""
     homepage = "http://crd-legacy.lbl.gov/~xiaoye/SuperLU/"
-    url      = "http://crd-legacy.lbl.gov/~xiaoye/SuperLU/superlu_dist_4.1.tar.gz"
+    url = "http://crd-legacy.lbl.gov/~xiaoye/SuperLU/superlu_dist_4.1.tar.gz"
 
     version('5.0.0', '2b53baf1b0ddbd9fcf724992577f0670')
     version('4.3', 'ee66c84e37b4f7cc557771ccc3dc43ae')
     version('4.2', 'ae9fafae161f775fbac6eba11e530a65')
     version('4.1', '4edee38cc29f687bd0c8eb361096a455')
     version('4.0', 'c0b98b611df227ae050bc1635c6940e0')
+    version('3.3', 'f4805659157d93a962500902c219046b')
 
     depends_on('mpi')
     depends_on('blas')
@@ -61,14 +62,13 @@ def install(self, spec, prefix):
             'ARCH         = ar',
             'ARCHFLAGS    = cr',
             'RANLIB       = true',
-            'CC           = %s' % spec['mpi'].mpicc,
-            'CFLAGS       = -fPIC -std=c99 -O2 -I%s -I%s' %
-                (spec['parmetis'].prefix.include,
-                 spec['metis'].prefix.include),
+            'CC           = {0}'.format(self.spec['mpi'].mpicc),
+            'CFLAGS       = -fPIC -std=c99 -O2 -I%s -I%s' % (
+                spec['parmetis'].prefix.include, spec['metis'].prefix.include),
             'NOOPTS       = -fPIC -std=c99',
-            'FORTRAN      = %s' % spec['mpi'].mpif77,
+            'FORTRAN      = {0}'.format(self.spec['mpi'].mpif77),
             'F90FLAGS     = -O2',
-            'LOADER       = %s' % spec['mpi'].mpif77,
+            'LOADER       = {0}'.format(self.spec['mpi'].mpif77),
             'LOADOPTS     =',
             'CDEFS        = -DAdd_'
         ])