diff --git a/var/spack/repos/builtin/packages/cp2k/package.py b/var/spack/repos/builtin/packages/cp2k/package.py
index 23edfd10b21bcda2e31ca91aa997105702e0a935..36b94926dab9cddd079b2ac6fcdc82f52e6b8b40 100644
--- a/var/spack/repos/builtin/packages/cp2k/package.py
+++ b/var/spack/repos/builtin/packages/cp2k/package.py
@@ -61,6 +61,14 @@ class Cp2k(MakefilePackage, CudaPackage):
     variant('cuda_blas', default=False,
             description=('Use CUBLAS for general matrix operations in DBCSR'))
 
+    HFX_LMAX_RANGE = range(4, 8)
+
+    variant('lmax',
+            description='Maximum supported angular momentum (HFX and others)',
+            default='5',
+            values=list(HFX_LMAX_RANGE),
+            multi=False)
+
     depends_on('python', type='build')
 
     depends_on('fftw@3:', when='~openmp')
@@ -80,11 +88,19 @@ class Cp2k(MakefilePackage, CudaPackage):
     depends_on('libxsmm@1.11:~header-only', when='smm=libxsmm')
     # use pkg-config (support added in libxsmm-1.10) to link to libxsmm
     depends_on('pkgconfig', type='build', when='smm=libxsmm')
+    # ... and in CP2K 7.0+ for linking to libint2
+    depends_on('pkgconfig', type='build', when='@7.0:')
 
     # libint & libxc are always statically linked
-    depends_on('libint@1.1.4:1.2', when='@3.0:', type='build')
+    depends_on('libint@1.1.4:1.2', when='@3.0:6.9', type='build')
+    for lmax in HFX_LMAX_RANGE:
+        # libint2 can be linked dynamically again
+        depends_on('libint@2.6.0:+fortran tune=cp2k-lmax-{0}'.format(lmax),
+                   when='@7.0: lmax={0}'.format(lmax))
+
     depends_on('libxc@2.2.2:', when='+libxc@:5.5999', type='build')
-    depends_on('libxc@4.0.3:', when='+libxc@6.0:', type='build')
+    depends_on('libxc@4.0.3:', when='+libxc@6.0:6.9', type='build')
+    depends_on('libxc@4.0.3:', when='+libxc@7.0:')
 
     depends_on('mpi@2:', when='+mpi')
     depends_on('scalapack', when='+mpi')
@@ -169,13 +185,17 @@ def edit(self, spec, prefix):
 
         dflags = ['-DNDEBUG']
         cppflags = [
-            '-D__FFTW3',
             '-D__LIBINT',
-            '-D__LIBINT_MAX_AM=6',
-            '-D__LIBDERIV_MAX_AM1=5',
+            '-D__FFTW3',
             fftw.headers.cpp_flags,
         ]
 
+        if '@:6.9' in spec:
+            cppflags += [
+                '-D__LIBINT_MAX_AM=6',
+                '-D__LIBDERIV_MAX_AM1=5',
+            ]
+
         if '^mpi@3:' in spec:
             cppflags.append('-D__MPI_VERSION=3')
         elif '^mpi@2:' in spec:
@@ -220,14 +240,18 @@ def edit(self, spec, prefix):
         if 'superlu-dist@4.3' in spec:
             ldflags.insert(0, '-Wl,--allow-multiple-definition')
 
-        # libint-1.x.y has to be linked statically to work around
-        # inconsistencies in its Fortran interface definition
-        # (short-int vs int) which otherwise causes segfaults at runtime
-        # due to wrong offsets into the shared library symbols.
-        libs.extend([
-            os.path.join(spec['libint'].libs.directories[0], 'libderiv.a'),
-            os.path.join(spec['libint'].libs.directories[0], 'libint.a'),
-        ])
+        if '@:6.9' in spec:
+            # libint-1.x.y has to be linked statically to work around
+            # inconsistencies in its Fortran interface definition
+            # (short-int vs int) which otherwise causes segfaults at runtime
+            # due to wrong offsets into the shared library symbols.
+            libs.extend([
+                os.path.join(spec['libint'].libs.directories[0], 'libderiv.a'),
+                os.path.join(spec['libint'].libs.directories[0], 'libint.a'),
+            ])
+        else:
+            fcflags += ['$(shell pkg-config --cflags libint2)']
+            libs += ['$(shell pkg-config --libs libint2)']
 
         if '+plumed' in self.spec:
             dflags.extend(['-D__PLUMED2'])
@@ -286,14 +310,16 @@ def edit(self, spec, prefix):
                 libs.append(wannier)
 
         if '+libxc' in spec:
-            libxc = spec['libxc:fortran,static']
-            cppflags += [
-                '-D__LIBXC',
-                libxc.headers.cpp_flags
-            ]
+            cppflags += ['-D__LIBXC']
 
-            ldflags.append(libxc.libs.search_flags)
-            libs.append(str(libxc.libs))
+            if '@:6.9' in spec:
+                libxc = spec['libxc:fortran,static']
+                cppflags += [libxc.headers.cpp_flags]
+                ldflags.append(libxc.libs.search_flags)
+                libs.append(str(libxc.libs))
+            else:
+                fcflags += ['$(shell pkg-config --cflags libxcf03)']
+                libs += ['$(shell pkg-config --libs libxcf03)']
 
         if '+pexsi' in self.spec:
             cppflags.append('-D__LIBPEXSI')
diff --git a/var/spack/repos/builtin/packages/libint/package.py b/var/spack/repos/builtin/packages/libint/package.py
index 08094d5c680b5bafb983b9b86b2cdadc2ba696f4..d58e4fec1d3c968b34967ad43f1b83744042e13e 100644
--- a/var/spack/repos/builtin/packages/libint/package.py
+++ b/var/spack/repos/builtin/packages/libint/package.py
@@ -3,9 +3,19 @@
 #
 # SPDX-License-Identifier: (Apache-2.0 OR MIT)
 
+import os
 from spack import *
 
 
+TUNE_VARIANTS = (
+    'none',
+    'cp2k-lmax-4',
+    'cp2k-lmax-5',
+    'cp2k-lmax-6',
+    'cp2k-lmax-7',
+)
+
+
 class Libint(AutotoolsPackage):
     """Libint is a high-performance library for computing
     Gaussian integrals in quantum mechanics.
@@ -14,6 +24,7 @@ class Libint(AutotoolsPackage):
     homepage = "https://github.com/evaleev/libint"
     url = "https://github.com/evaleev/libint/archive/v2.1.0.tar.gz"
 
+    version('2.6.0', sha256='4ae47e8f0b5632c3d2a956469a7920896708e9f0e396ec10071b8181e4c8d9fa')
     version('2.4.2', sha256='86dff38065e69a3a51d15cfdc638f766044cb87e5c6682d960c14f9847e2eac3')
     version('2.4.1', sha256='0513be124563fdbbc7cd3c7043e221df1bda236a037027ba9343429a27db8ce4')
     version('2.4.0', sha256='52eb16f065406099dcfaceb12f9a7f7e329c9cfcf6ed9bfacb0cff7431dd6019')
@@ -22,6 +33,12 @@ class Libint(AutotoolsPackage):
     version('1.1.6', sha256='f201b0c621df678cfe8bdf3990796b8976ff194aba357ae398f2f29b0e2985a6')
     version('1.1.5', sha256='ec8cd4a4ba1e1a98230165210c293632372f0e573acd878ed62e5ec6f8b6174b')
 
+    variant('fortran', default=False,
+            description='Build & install Fortran bindings')
+    variant('tune', default='none', multi=False,
+            values=TUNE_VARIANTS,
+            description='Tune libint for use with the given package')
+
     # Build dependencies
     depends_on('autoconf@2.52:', type='build')
     depends_on('automake', type='build')
@@ -31,6 +48,11 @@ class Libint(AutotoolsPackage):
     depends_on('boost', when='@2:')
     depends_on('gmp', when='@2:')
 
+    for tvariant in TUNE_VARIANTS[1:]:
+        conflicts('tune={0}'.format(tvariant), when='@:2.5.99',
+                  msg=('for versions prior to 2.6, tuning for specific'
+                       'codes/configurations is not supported'))
+
     def url_for_version(self, version):
         base_url = "https://github.com/evaleev/libint/archive"
         if version == Version('1.0.0'):
@@ -45,6 +67,10 @@ def autoreconf(self, spec, prefix):
         aclocal('-I', 'lib/autoconf')
         autoconf()
 
+        if '@2.6.0:' in spec:
+            # skip tarball creation and removal of dir with generated code
+            filter_file(r'^(export::.*)\s+tgz$', r'\1', 'export/Makefile')
+
     @property
     def optflags(self):
         flags = '-O2'
@@ -89,4 +115,60 @@ def configure_args(self):
                 '--with-libint-max-am=5',
                 '--with-libderiv-max-am1=4'
             ])
+
+        if '@2.6.0:' in self.spec:
+            config_args += ['--with-libint-exportdir=generated']
+
+            tune_value = self.spec.variants['tune'].value
+            if tune_value.startswith('cp2k'):
+                lmax = int(tune_value.split('-lmax-')[1])
+                config_args += [
+                    '--enable-eri=1',
+                    '--enable-eri2=1',
+                    '--enable-eri3=1',
+                    '--with-max-am={0}'.format(lmax),
+                    '--with-eri-max-am={0},{1}'.format(lmax, lmax - 1),
+                    '--with-eri2-max-am={0},{1}'.format(lmax + 2, lmax + 1),
+                    '--with-eri3-max-am={0},{1}'.format(lmax + 2, lmax + 1),
+                    '--with-opt-am=3',
+                    # keep code-size at an acceptable limit,
+                    # cf. https://github.com/evaleev/libint/wiki#program-specific-notes:
+                    '--enable-generic-code',
+                    '--disable-unrolling',
+                ]
+
         return config_args
+
+    @property
+    def build_targets(self):
+        if '@2.6.0:' in self.spec:
+            return ['export']
+
+        return []
+
+    @when('@2.6.0:')
+    def install(self, spec, prefix):
+        """
+        Starting from libint 2.6.0 we're using the 2-stage build
+        to get support for the Fortran bindings, required by some
+        packages (CP2K notably).
+        """
+
+        # upstream says that using configure/make for the generated code
+        # is deprecated and one should use CMake, but with the currently
+        # recent 2.7.0.b1 it still doesn't work
+        with working_dir(os.path.join(self.build_directory, 'generated')):
+            # straight from the AutotoolsPackage class:
+            options = [
+                '--prefix={0}'.format(prefix),
+                '--enable-shared',
+                '--with-cxx-optflags={0}'.format(self.optflags),
+            ]
+
+            if '+fortran' in spec:
+                options += ['--enable-fortran']
+
+            configure = Executable('./configure')
+            configure(*options)
+            make()
+            make('install')