diff --git a/config/components.yml b/config/components.yml
index 9011950635..933bf1a413 100644
--- a/config/components.yml
+++ b/config/components.yml
@@ -71,6 +71,7 @@ frameworks:
- "JavaBuildpack::Framework::SealightsAgent"
- "JavaBuildpack::Framework::SeekerSecurityProvider"
- "JavaBuildpack::Framework::SpringAutoReconfiguration"
+ - "JavaBuildpack::Framework::SplunkOtelJavaAgent"
- "JavaBuildpack::Framework::SpringInsight"
- "JavaBuildpack::Framework::SkyWalkingAgent"
- "JavaBuildpack::Framework::YourKitProfiler"
diff --git a/config/splunk_otel_java_agent.yml b/config/splunk_otel_java_agent.yml
new file mode 100644
index 0000000000..7a3824cf67
--- /dev/null
+++ b/config/splunk_otel_java_agent.yml
@@ -0,0 +1,21 @@
+# Cloud Foundry Java Buildpack
+# Copyright 2013-2020 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Configuration for the Splunk Distribution of OpenTelemetry Java Instrumentation
+# See https://github.com/signalfx/splunk-otel-java for more information
+---
+version: +
+repository_root: https://raw.githubusercontent.com/signalfx/splunk-otel-java/main/deployments/cloudfoundry/
+
\ No newline at end of file
diff --git a/docs/framework-splunk_otel_java_agent.md b/docs/framework-splunk_otel_java_agent.md
new file mode 100644
index 0000000000..0ba30e97d5
--- /dev/null
+++ b/docs/framework-splunk_otel_java_agent.md
@@ -0,0 +1,60 @@
+# Splunk Distribution of OpenTelemetry Java Instrumentation
+
+The Splunk OpenTelemetry Java Agent buildpack framework will cause an application to be automatically instrumented
+with the [Splunk distribution of OpenTelemetry Java Instrumentation](https://github.com/signalfx/splunk-otel-java).
+
+Trace data will be sent directly to Splunk Observability Cloud.
+
+
+
+ | Detection Criterion |
+ Existence of a bound service containing the string splunk-o11y |
+
+
+ | Tags |
+ splunk-otel-java-agent=<version> |
+
+
+
+Tags are printed to standard output by the buildpack detect script
+
+## User-Provided Service
+
+Users are currently expected to provide their own "custom user provided service" (cups)
+instance and bind it to their application. The service MUST contain the string `splunk-o11y`.
+
+For example, to create a service named `splunk-o11y` that represents Observability Cloud
+realm `us0` and represents a user environment named `cf-demo`, you could use the following
+commands:
+
+```
+$ cf cups splunk-o11y -p \
+ '{"splunk.realm": "us0", "splunk.access.token": "", "otel.resource.attributes": "deployment.environment=cf-demo"}'
+$ cf bind-service myApp splunk-o11y
+$ cf restage myApp
+```
+
+The `credential` field of the service should provide these entries:
+
+| Name | Required? | Description
+|------------------------|-----------| -----------
+| `splunk.access.token` | Yes | The Splunk [org access token](https://docs.splunk.com/observability/admin/authentication-tokens/org-tokens.html).
+| `splunk.realm` | Yes | The Splunk realm where data will be sent. This is commonly `us0` or `eu0` etc.
+| `otel.*` or `splunk.*` | Optional | All additional credentials starting with these prefixes will be appended to the application's JVM arguments as system properties.
+
+### Choosing a version
+
+Most users should skip this and simply use the latest version of the agent available (the default).
+To override the default and choose a specific version, you can use the `JBP_CONFIG_*` mechanism
+and set the `JBP_CONFIG_SPLUNK_OTEL_JAVA_AGENT` environment variable for your application.
+
+For example, to use version 1.16.0 of the Splunk OpenTelemetry Java Instrumentation, you
+could run:
+```
+$ cf set-env testapp JBP_CONFIG_SPLUNK_OTEL_JAVA_AGENT '{version: 1.16.0}'
+```
+
+# Additional Resources
+
+* [Splunk Observability](https://www.splunk.com/en_us/products/observability.html)
+* [Splunk Distribution of OpenTelemetry Java](https://github.com/signalfx/splunk-otel-java) on GitHub
diff --git a/lib/java_buildpack/framework/splunk_otel_java_agent.rb b/lib/java_buildpack/framework/splunk_otel_java_agent.rb
new file mode 100644
index 0000000000..f3361a869d
--- /dev/null
+++ b/lib/java_buildpack/framework/splunk_otel_java_agent.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+# Cloud Foundry Java Buildpack
+# Copyright 2013-2020 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'java_buildpack/component/versioned_dependency_component'
+require 'java_buildpack/framework'
+
+module JavaBuildpack
+ module Framework
+
+ # Main class for adding the Splunk OpenTelemetry instrumentation agent
+ class SplunkOtelJavaAgent < JavaBuildpack::Component::VersionedDependencyComponent
+
+ # (see JavaBuildpack::Component::BaseComponent#compile)
+ def compile
+ download_jar
+ end
+
+ # (see JavaBuildpack::Component::BaseComponent#release)
+ def release
+ java_opts = @droplet.java_opts
+ java_opts.add_javaagent(@droplet.sandbox + jar_name)
+
+ credentials = @application.services.find_service(REQUIRED_SERVICE_NAME_FILTER)['credentials']
+ # Add all otel.* and splunk.* credentials from the service bind as jvm system properties
+ credentials&.each do |key, value|
+ java_opts.add_system_property(key, value) if key.start_with?('splunk.') || key.start_with?('otel.')
+ end
+
+ # Set the otel.service.name to the application_name if not specified in credentials
+ return if credentials.key? 'otel.service.name'
+
+ app_name = @application.details['application_name']
+ java_opts.add_system_property('otel.service.name', app_name)
+ end
+
+ protected
+
+ # (see JavaBuildpack::Component::VersionedDependencyComponent#supports?)
+ def supports?
+ @application.services.one_service? REQUIRED_SERVICE_NAME_FILTER
+ end
+
+ # bound service must contain the string `splunk-o11y`
+ REQUIRED_SERVICE_NAME_FILTER = /splunk-o11y/.freeze
+
+ end
+ end
+end
diff --git a/spec/fixtures/stub-splunk-otel-javaagent.jar b/spec/fixtures/stub-splunk-otel-javaagent.jar
new file mode 100644
index 0000000000..0878c3ccb5
Binary files /dev/null and b/spec/fixtures/stub-splunk-otel-javaagent.jar differ
diff --git a/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb b/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb
new file mode 100644
index 0000000000..eb75ada8e5
--- /dev/null
+++ b/spec/java_buildpack/framework/splunk_otel_java_agent_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+# Cloud Foundry Java Buildpack
+# Copyright 2013-2020 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+require 'spec_helper'
+require 'component_helper'
+require 'java_buildpack/framework/splunk_otel_java_agent'
+require 'java_buildpack/util/tokenized_version'
+
+describe JavaBuildpack::Framework::SplunkOtelJavaAgent do
+ include_context 'with component help'
+
+ let(:configuration) { { 'version' => '1.16.0' } }
+ let(:vcap_application) { { 'application_name' => 'GreatServiceTM' } }
+
+ it 'does not detect without splunk-o11y service bind' do
+ expect(component.detect).to be_nil
+ end
+
+ context 'when detected' do
+
+ before do
+ allow(services).to receive(:one_service?).with(/splunk-o11y/).and_return(true)
+ end
+
+ it 'detects with splunk-otel-java' do
+ expect(component.detect).to eq("splunk-otel-java-agent=#{version}")
+ end
+
+ it 'downloads the splunk otel javaagent jar', cache_fixture: 'stub-splunk-otel-javaagent.jar' do
+
+ component.compile
+
+ expect(sandbox + "splunk_otel_java_agent-#{version}.jar").to exist
+ end
+
+ it 'updates JAVA_OPTS' do
+ allow(services).to receive(:find_service).and_return('credentials' => { 'splunk.access.token' => 'sekret',
+ 'ignored' => 'not used',
+ 'otel.foo' => 'bar' })
+ component.release
+
+ expect(java_opts).to include(
+ "-javaagent:$PWD/.java-buildpack/splunk_otel_java_agent/splunk_otel_java_agent-#{version}.jar"
+ )
+ expect(java_opts).to include('-Dsplunk.access.token=sekret')
+ expect(java_opts).to include('-Dotel.foo=bar')
+ end
+
+ it 'sets the service name from the application name' do
+ allow(services).to receive(:find_service).and_return('credentials' => { 'splunk.access.token' => 'sekret' })
+
+ component.release
+
+ expect(java_opts).to include('-Dotel.service.name=GreatServiceTM')
+ end
+
+ it 'prefers credentials over application_name for service name' do
+ creds = { 'credentials' => { 'otel.service.name' => 'sweet', 'splunk.access.token' => 'sekret' } }
+ allow(services).to receive(:find_service).and_return(creds)
+
+ component.release
+
+ expect(java_opts).to include('-Dotel.service.name=sweet')
+ end
+
+ end
+
+end